blob: e4050a9e92a64d4f9711eab7f66fa71bec90435c [file] [log] [blame]
jvanverth50530632015-04-27 10:36:27 -07001/*
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
joshualitt8072caa2015-02-12 14:20:52 -08008#include "GrPathProcessor.h"
9
joshualitt8072caa2015-02-12 14:20:52 -080010#include "gl/GrGLGpu.h"
11
jvanverthcba99b82015-06-24 06:59:57 -070012#include "glsl/GrGLSLCaps.h"
13
joshualitt102081a2015-09-11 11:52:17 -070014class GrGLPathProcessor : public GrGLPrimitiveProcessor {
15public:
16 GrGLPathProcessor() : fColor(GrColor_ILLEGAL) {}
17
18 static void GenKey(const GrPathProcessor& pathProc,
19 const GrGLSLCaps&,
20 GrProcessorKeyBuilder* b) {
21 b->add32(SkToInt(pathProc.opts().readsColor()) |
22 SkToInt(pathProc.opts().readsCoverage()) << 16);
23 }
24
25 void emitCode(EmitArgs& args) override {
26 GrGLGPBuilder* pb = args.fPB;
27 GrGLFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder();
28 const GrPathProcessor& pathProc = args.fGP.cast<GrPathProcessor>();
29
30 // emit transforms
31 this->emitTransforms(args.fPB, args.fTransformsIn, args.fTransformsOut);
32
33 // Setup uniform color
34 if (pathProc.opts().readsColor()) {
35 const char* stagedLocalVarName;
36 fColorUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility,
37 kVec4f_GrSLType,
38 kDefault_GrSLPrecision,
39 "Color",
40 &stagedLocalVarName);
41 fs->codeAppendf("%s = %s;", args.fOutputColor, stagedLocalVarName);
42 }
43
44 // setup constant solid coverage
45 if (pathProc.opts().readsCoverage()) {
46 fs->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
47 }
48 }
49
50 void emitTransforms(GrGLGPBuilder* pb, const TransformsIn& tin, TransformsOut* tout) {
51 tout->push_back_n(tin.count());
52 fInstalledTransforms.push_back_n(tin.count());
53 for (int i = 0; i < tin.count(); i++) {
54 const ProcCoords& coordTransforms = tin[i];
55 fInstalledTransforms[i].push_back_n(coordTransforms.count());
56 for (int t = 0; t < coordTransforms.count(); t++) {
57 GrSLType varyingType =
58 coordTransforms[t]->getMatrix().hasPerspective() ? kVec3f_GrSLType :
59 kVec2f_GrSLType;
60
61 SkString strVaryingName("MatrixCoord");
62 strVaryingName.appendf("_%i_%i", i, t);
63 GrGLVertToFrag v(varyingType);
64 fInstalledTransforms[i][t].fHandle =
65 pb->addSeparableVarying(strVaryingName.c_str(), &v).toIndex();
66 fInstalledTransforms[i][t].fType = varyingType;
67
68 SkNEW_APPEND_TO_TARRAY(&(*tout)[i], GrGLProcessor::TransformedCoords,
69 (SkString(v.fsIn()), varyingType));
70 }
71 }
72 }
73
egdaniel018fb622015-10-28 07:26:40 -070074 void setData(const GrGLSLProgramDataManager& pd,
75 const GrPrimitiveProcessor& primProc) override {
joshualitt102081a2015-09-11 11:52:17 -070076 const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
77 if (pathProc.opts().readsColor() && pathProc.color() != fColor) {
egdaniel018fb622015-10-28 07:26:40 -070078 float c[4];
joshualitt102081a2015-09-11 11:52:17 -070079 GrColorToRGBAFloat(pathProc.color(), c);
80 pd.set4fv(fColorUniform, 1, c);
81 fColor = pathProc.color();
82 }
83 }
84
85 void setTransformData(const GrPrimitiveProcessor& primProc,
egdaniel018fb622015-10-28 07:26:40 -070086 const GrGLSLProgramDataManager& pdman,
joshualitt102081a2015-09-11 11:52:17 -070087 int index,
88 const SkTArray<const GrCoordTransform*, true>& coordTransforms) override {
89 const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
90 SkSTArray<2, Transform, true>& transforms = fInstalledTransforms[index];
91 int numTransforms = transforms.count();
92 for (int t = 0; t < numTransforms; ++t) {
93 SkASSERT(transforms[t].fHandle.isValid());
94 const SkMatrix& transform = GetTransformMatrix(pathProc.localMatrix(),
95 *coordTransforms[t]);
96 if (transforms[t].fCurrentValue.cheapEqualTo(transform)) {
97 continue;
98 }
99 transforms[t].fCurrentValue = transform;
100
101 SkASSERT(transforms[t].fType == kVec2f_GrSLType ||
102 transforms[t].fType == kVec3f_GrSLType);
103 unsigned components = transforms[t].fType == kVec2f_GrSLType ? 2 : 3;
104 pdman.setPathFragmentInputTransform(transforms[t].fHandle, components, transform);
105 }
106 }
107
108private:
109 UniformHandle fColorUniform;
110 GrColor fColor;
111
112 typedef GrGLPrimitiveProcessor INHERITED;
113};
114
joshualitt8072caa2015-02-12 14:20:52 -0800115GrPathProcessor::GrPathProcessor(GrColor color,
joshualittf2384692015-09-10 11:00:51 -0700116 const GrPipelineOptimizations& opts,
joshualitt8072caa2015-02-12 14:20:52 -0800117 const SkMatrix& viewMatrix,
118 const SkMatrix& localMatrix)
joshualitte3ababe2015-05-15 07:56:07 -0700119 : INHERITED(true)
120 , fColor(color)
joshualitte578a952015-05-14 10:09:13 -0700121 , fViewMatrix(viewMatrix)
joshualittf2384692015-09-10 11:00:51 -0700122 , fLocalMatrix(localMatrix)
123 , fOpts(opts) {
joshualitt8072caa2015-02-12 14:20:52 -0800124 this->initClassID<GrPathProcessor>();
125}
126
joshualitt465283c2015-09-11 08:19:35 -0700127void GrPathProcessor::getGLProcessorKey(const GrGLSLCaps& caps,
joshualitt8072caa2015-02-12 14:20:52 -0800128 GrProcessorKeyBuilder* b) const {
joshualitt465283c2015-09-11 08:19:35 -0700129 GrGLPathProcessor::GenKey(*this, caps, b);
joshualitt8072caa2015-02-12 14:20:52 -0800130}
131
joshualitt465283c2015-09-11 08:19:35 -0700132GrGLPrimitiveProcessor* GrPathProcessor::createGLInstance(const GrGLSLCaps& caps) const {
jvanverth50530632015-04-27 10:36:27 -0700133 SkASSERT(caps.pathRenderingSupport());
joshualitt465283c2015-09-11 08:19:35 -0700134 return new GrGLPathProcessor();
joshualitt8072caa2015-02-12 14:20:52 -0800135}