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 "src/gpu/GrPathProcessor.h"
9
10 #include "include/private/SkTo.h"
11 #include "src/gpu/GrShaderCaps.h"
12 #include "src/gpu/gl/GrGLGpu.h"
13 #include "src/gpu/gl/GrGLVaryingHandler.h"
14 #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
15 #include "src/gpu/glsl/GrGLSLPrimitiveProcessor.h"
16 #include "src/gpu/glsl/GrGLSLUniformHandler.h"
17 #include "src/gpu/glsl/GrGLSLVarying.h"
18
19 class GrGLPathProcessor : public GrGLSLPrimitiveProcessor {
20 public:
GrGLPathProcessor()21 GrGLPathProcessor() : fColor(SK_PMColor4fILLEGAL) {}
22
GenKey(const GrPathProcessor & pathProc,const GrShaderCaps &,GrProcessorKeyBuilder * b)23 static void GenKey(const GrPathProcessor& pathProc,
24 const GrShaderCaps&,
25 GrProcessorKeyBuilder* b) {
26 b->add32(SkToInt(pathProc.viewMatrix().hasPerspective()));
27 }
28
emitCode(EmitArgs & args)29 void emitCode(EmitArgs& args) override {
30 GrGLSLFPFragmentBuilder* 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.fFPCoordTransformHandler);
39
40 // Setup uniform color
41 const char* stagedLocalVarName;
42 fColorUniform = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
43 kHalf4_GrSLType,
44 "Color",
45 &stagedLocalVarName);
46 fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, stagedLocalVarName);
47
48 // setup constant solid coverage
49 fragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
50 }
51
emitTransforms(GrGLSLVaryingHandler * varyingHandler,FPCoordTransformHandler * transformHandler)52 void emitTransforms(GrGLSLVaryingHandler* varyingHandler,
53 FPCoordTransformHandler* transformHandler) {
54 int i = 0;
55 while (const GrCoordTransform* coordTransform = transformHandler->nextCoordTransform()) {
56 GrSLType varyingType =
57 coordTransform->getMatrix().hasPerspective() ? kHalf3_GrSLType
58 : kHalf2_GrSLType;
59
60 SkString strVaryingName;
61 strVaryingName.printf("TransformedCoord_%d", i);
62 GrGLSLVarying v(varyingType);
63 GrGLVaryingHandler* glVaryingHandler = (GrGLVaryingHandler*) varyingHandler;
64 fInstalledTransforms.push_back().fHandle =
65 glVaryingHandler->addPathProcessingVarying(strVaryingName.c_str(),
66 &v).toIndex();
67 fInstalledTransforms.back().fType = varyingType;
68
69 transformHandler->specifyCoordsForCurrCoordTransform(SkString(v.fsIn()), varyingType);
70 ++i;
71 }
72 }
73
setData(const GrGLSLProgramDataManager & pd,const GrPrimitiveProcessor & primProc,FPCoordTransformIter && transformIter)74 void setData(const GrGLSLProgramDataManager& pd,
75 const GrPrimitiveProcessor& primProc,
76 FPCoordTransformIter&& transformIter) override {
77 const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
78 if (pathProc.color() != fColor) {
79 pd.set4fv(fColorUniform, 1, pathProc.color().vec());
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 == kHalf2_GrSLType ||
93 fInstalledTransforms[t].fType == kHalf3_GrSLType);
94 unsigned components = fInstalledTransforms[t].fType == kHalf2_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 SkPMColor4f fColor;
112
113 typedef GrGLSLPrimitiveProcessor INHERITED;
114 };
115
GrPathProcessor(const SkPMColor4f & color,const SkMatrix & viewMatrix,const SkMatrix & localMatrix)116 GrPathProcessor::GrPathProcessor(const SkPMColor4f& color,
117 const SkMatrix& viewMatrix,
118 const SkMatrix& localMatrix)
119 : INHERITED(kGrPathProcessor_ClassID)
120 , fColor(color)
121 , fViewMatrix(viewMatrix)
122 , fLocalMatrix(localMatrix) {}
123
getGLSLProcessorKey(const GrShaderCaps & caps,GrProcessorKeyBuilder * b) const124 void GrPathProcessor::getGLSLProcessorKey(const GrShaderCaps& caps,
125 GrProcessorKeyBuilder* b) const {
126 GrGLPathProcessor::GenKey(*this, caps, b);
127 }
128
createGLSLInstance(const GrShaderCaps & caps) const129 GrGLSLPrimitiveProcessor* GrPathProcessor::createGLSLInstance(const GrShaderCaps& caps) const {
130 SkASSERT(caps.pathRenderingSupport());
131 return new GrGLPathProcessor();
132 }
133