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