1 /*
2 * Copyright 2013 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 "GrPathProcessor.h"
9
10 #include "GrShaderCaps.h"
11 #include "gl/GrGLGpu.h"
12 #include "glsl/GrGLSLFragmentShaderBuilder.h"
13 #include "glsl/GrGLSLUniformHandler.h"
14 #include "glsl/GrGLSLVarying.h"
15
16 class GrGLPathProcessor : public GrGLSLPrimitiveProcessor {
17 public:
GrGLPathProcessor()18 GrGLPathProcessor() : fColor(GrColor_ILLEGAL) {}
19
GenKey(const GrPathProcessor & pathProc,const GrShaderCaps &,GrProcessorKeyBuilder * b)20 static void GenKey(const GrPathProcessor& pathProc,
21 const GrShaderCaps&,
22 GrProcessorKeyBuilder* b) {
23 b->add32(SkToInt(pathProc.viewMatrix().hasPerspective()));
24 }
25
emitCode(EmitArgs & args)26 void emitCode(EmitArgs& args) override {
27 GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
28 const GrPathProcessor& pathProc = args.fGP.cast<GrPathProcessor>();
29
30 if (!pathProc.viewMatrix().hasPerspective()) {
31 args.fVaryingHandler->setNoPerspective();
32 }
33
34 // emit transforms
35 this->emitTransforms(args.fVaryingHandler, args.fFPCoordTransformHandler);
36
37 // Setup uniform color
38 const char* stagedLocalVarName;
39 fColorUniform = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
40 kVec4f_GrSLType,
41 kDefault_GrSLPrecision,
42 "Color",
43 &stagedLocalVarName);
44 fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, stagedLocalVarName);
45
46 // setup constant solid coverage
47 fragBuilder->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
48 }
49
emitTransforms(GrGLSLVaryingHandler * varyingHandler,FPCoordTransformHandler * transformHandler)50 void emitTransforms(GrGLSLVaryingHandler* varyingHandler,
51 FPCoordTransformHandler* transformHandler) {
52 int i = 0;
53 while (const GrCoordTransform* coordTransform = transformHandler->nextCoordTransform()) {
54 GrSLType varyingType =
55 coordTransform->getMatrix().hasPerspective() ? kVec3f_GrSLType
56 : kVec2f_GrSLType;
57
58 SkString strVaryingName;
59 strVaryingName.printf("TransformedCoord_%d", i);
60 GrGLSLVertToFrag v(varyingType);
61 GrGLVaryingHandler* glVaryingHandler = (GrGLVaryingHandler*) varyingHandler;
62 fInstalledTransforms.push_back().fHandle =
63 glVaryingHandler->addPathProcessingVarying(strVaryingName.c_str(),
64 &v).toIndex();
65 fInstalledTransforms.back().fType = varyingType;
66
67 transformHandler->specifyCoordsForCurrCoordTransform(SkString(v.fsIn()), varyingType);
68 ++i;
69 }
70 }
71
setData(const GrGLSLProgramDataManager & pd,const GrPrimitiveProcessor & primProc,FPCoordTransformIter && transformIter)72 void setData(const GrGLSLProgramDataManager& pd,
73 const GrPrimitiveProcessor& primProc,
74 FPCoordTransformIter&& transformIter) override {
75 const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
76 if (pathProc.color() != fColor) {
77 float c[4];
78 GrColorToRGBAFloat(pathProc.color(), c);
79 pd.set4fv(fColorUniform, 1, c);
80 fColor = pathProc.color();
81 }
82
83 int t = 0;
84 while (const GrCoordTransform* coordTransform = transformIter.next()) {
85 SkASSERT(fInstalledTransforms[t].fHandle.isValid());
86 const SkMatrix& m = GetTransformMatrix(pathProc.localMatrix(), *coordTransform);
87 if (fInstalledTransforms[t].fCurrentValue.cheapEqualTo(m)) {
88 continue;
89 }
90 fInstalledTransforms[t].fCurrentValue = m;
91
92 SkASSERT(fInstalledTransforms[t].fType == kVec2f_GrSLType ||
93 fInstalledTransforms[t].fType == kVec3f_GrSLType);
94 unsigned components = fInstalledTransforms[t].fType == kVec2f_GrSLType ? 2 : 3;
95 pd.setPathFragmentInputTransform(fInstalledTransforms[t].fHandle, components, m);
96 ++t;
97 }
98 }
99
100 private:
101 typedef GrGLSLProgramDataManager::VaryingHandle VaryingHandle;
102 struct TransformVarying {
103 VaryingHandle fHandle;
104 SkMatrix fCurrentValue = SkMatrix::InvalidMatrix();
105 GrSLType fType = kVoid_GrSLType;
106 };
107
108 SkTArray<TransformVarying, true> fInstalledTransforms;
109
110 UniformHandle fColorUniform;
111 GrColor fColor;
112
113 typedef GrGLSLPrimitiveProcessor INHERITED;
114 };
115
GrPathProcessor(GrColor color,const SkMatrix & viewMatrix,const SkMatrix & localMatrix)116 GrPathProcessor::GrPathProcessor(GrColor color,
117 const SkMatrix& viewMatrix,
118 const SkMatrix& localMatrix)
119 : fColor(color)
120 , fViewMatrix(viewMatrix)
121 , fLocalMatrix(localMatrix) {
122 this->initClassID<GrPathProcessor>();
123 }
124
getGLSLProcessorKey(const GrShaderCaps & caps,GrProcessorKeyBuilder * b) const125 void GrPathProcessor::getGLSLProcessorKey(const GrShaderCaps& caps,
126 GrProcessorKeyBuilder* b) const {
127 GrGLPathProcessor::GenKey(*this, caps, b);
128 }
129
createGLSLInstance(const GrShaderCaps & caps) const130 GrGLSLPrimitiveProcessor* GrPathProcessor::createGLSLInstance(const GrShaderCaps& caps) const {
131 SkASSERT(caps.pathRenderingSupport());
132 return new GrGLPathProcessor();
133 }
134