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