• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/GrGLSLProcessorTypes.h"
14 #include "glsl/GrGLSLUniformHandler.h"
15 #include "glsl/GrGLSLVarying.h"
16 
17 class GrGLPathProcessor : public GrGLSLPrimitiveProcessor {
18 public:
GrGLPathProcessor()19     GrGLPathProcessor() : fColor(GrColor_ILLEGAL) {}
20 
GenKey(const GrPathProcessor & pathProc,const GrGLSLCaps &,GrProcessorKeyBuilder * b)21     static void GenKey(const GrPathProcessor& pathProc,
22                        const GrGLSLCaps&,
23                        GrProcessorKeyBuilder* b) {
24         b->add32(SkToInt(pathProc.overrides().readsColor()) |
25                  (SkToInt(pathProc.overrides().readsCoverage()) << 1) |
26                  (SkToInt(pathProc.viewMatrix().hasPerspective()) << 2));
27     }
28 
emitCode(EmitArgs & args)29     void emitCode(EmitArgs& args) override {
30         GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
31         const GrPathProcessor& pathProc = args.fGP.cast<GrPathProcessor>();
32 
33         if (!pathProc.viewMatrix().hasPerspective()) {
34             args.fVaryingHandler->setNoPerspective();
35         }
36 
37         // emit transforms
38         this->emitTransforms(args.fVaryingHandler, args.fTransformsIn, args.fTransformsOut);
39 
40         // Setup uniform color
41         if (pathProc.overrides().readsColor()) {
42             const char* stagedLocalVarName;
43             fColorUniform = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
44                                                              kVec4f_GrSLType,
45                                                              kDefault_GrSLPrecision,
46                                                              "Color",
47                                                              &stagedLocalVarName);
48             fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, stagedLocalVarName);
49         }
50 
51         // setup constant solid coverage
52         if (pathProc.overrides().readsCoverage()) {
53             fragBuilder->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
54         }
55     }
56 
emitTransforms(GrGLSLVaryingHandler * varyingHandler,const TransformsIn & tin,TransformsOut * tout)57     void emitTransforms(GrGLSLVaryingHandler* varyingHandler,
58                         const TransformsIn& tin,
59                         TransformsOut* tout) {
60         tout->push_back_n(tin.count());
61         fInstalledTransforms.push_back_n(tin.count());
62         for (int i = 0; i < tin.count(); i++) {
63             const ProcCoords& coordTransforms = tin[i];
64             fInstalledTransforms[i].push_back_n(coordTransforms.count());
65             for (int t = 0; t < coordTransforms.count(); t++) {
66                 GrSLType varyingType =
67                         coordTransforms[t]->getMatrix().hasPerspective() ? kVec3f_GrSLType :
68                                                                            kVec2f_GrSLType;
69 
70                 SkString strVaryingName("MatrixCoord");
71                 strVaryingName.appendf("_%i_%i", i, t);
72                 GrGLSLVertToFrag v(varyingType);
73                 GrGLVaryingHandler* glVaryingHandler = (GrGLVaryingHandler*) varyingHandler;
74                 fInstalledTransforms[i][t].fHandle =
75                         glVaryingHandler->addPathProcessingVarying(strVaryingName.c_str(),
76                                                                    &v).toIndex();
77                 fInstalledTransforms[i][t].fType = varyingType;
78 
79                 (*tout)[i].emplace_back(SkString(v.fsIn()), varyingType);
80             }
81         }
82     }
83 
setData(const GrGLSLProgramDataManager & pd,const GrPrimitiveProcessor & primProc)84     void setData(const GrGLSLProgramDataManager& pd,
85                  const GrPrimitiveProcessor& primProc) override {
86         const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
87         if (pathProc.overrides().readsColor() && pathProc.color() != fColor) {
88             float c[4];
89             GrColorToRGBAFloat(pathProc.color(), c);
90             pd.set4fv(fColorUniform, 1, c);
91             fColor = pathProc.color();
92         }
93     }
94 
setTransformData(const GrPrimitiveProcessor & primProc,const GrGLSLProgramDataManager & pdman,int index,const SkTArray<const GrCoordTransform *,true> & coordTransforms)95     void setTransformData(const GrPrimitiveProcessor& primProc,
96                           const GrGLSLProgramDataManager& pdman,
97                           int index,
98                           const SkTArray<const GrCoordTransform*, true>& coordTransforms) override {
99         const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
100         SkSTArray<2, Transform, true>& transforms = fInstalledTransforms[index];
101         int numTransforms = transforms.count();
102         for (int t = 0; t < numTransforms; ++t) {
103             SkASSERT(transforms[t].fHandle.isValid());
104             const SkMatrix& transform = GetTransformMatrix(pathProc.localMatrix(),
105                                                            *coordTransforms[t]);
106             if (transforms[t].fCurrentValue.cheapEqualTo(transform)) {
107                 continue;
108             }
109             transforms[t].fCurrentValue = transform;
110 
111             SkASSERT(transforms[t].fType == kVec2f_GrSLType ||
112                      transforms[t].fType == kVec3f_GrSLType);
113             unsigned components = transforms[t].fType == kVec2f_GrSLType ? 2 : 3;
114             pdman.setPathFragmentInputTransform(transforms[t].fHandle, components, transform);
115         }
116     }
117 
118 private:
119     UniformHandle fColorUniform;
120     GrColor fColor;
121 
122     typedef GrGLSLPrimitiveProcessor INHERITED;
123 };
124 
GrPathProcessor(GrColor color,const GrXPOverridesForBatch & overrides,const SkMatrix & viewMatrix,const SkMatrix & localMatrix)125 GrPathProcessor::GrPathProcessor(GrColor color,
126                                  const GrXPOverridesForBatch& overrides,
127                                  const SkMatrix& viewMatrix,
128                                  const SkMatrix& localMatrix)
129     : fColor(color)
130     , fViewMatrix(viewMatrix)
131     , fLocalMatrix(localMatrix)
132     , fOverrides(overrides) {
133     this->initClassID<GrPathProcessor>();
134 }
135 
getGLSLProcessorKey(const GrGLSLCaps & caps,GrProcessorKeyBuilder * b) const136 void GrPathProcessor::getGLSLProcessorKey(const GrGLSLCaps& caps,
137                                           GrProcessorKeyBuilder* b) const {
138     GrGLPathProcessor::GenKey(*this, caps, b);
139 }
140 
createGLSLInstance(const GrGLSLCaps & caps) const141 GrGLSLPrimitiveProcessor* GrPathProcessor::createGLSLInstance(const GrGLSLCaps& caps) const {
142     SkASSERT(caps.pathRenderingSupport());
143     return new GrGLPathProcessor();
144 }
145