blob: 6bd6b2b54badd963b3a5794e301476f2a1cb3d48 [file] [log] [blame]
joshualitt9b989322014-12-15 14:16:27 -08001/*
2 * Copyright 2014 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 "GrGeometryProcessor.h"
9
10#include "gl/GrGLGeometryProcessor.h"
11#include "GrInvariantOutput.h"
12
13///////////////////////////////////////////////////////////////////////////////////////////////////
14
15void GrGeometryProcessor::getInvariantOutputColor(GrInitInvariantOutput* out) const {
16 if (fHasVertexColor) {
17 if (fOpaqueVertexColors) {
18 out->setUnknownOpaqueFourComponents();
19 } else {
20 out->setUnknownFourComponents();
21 }
22 } else {
23 out->setKnownFourComponents(fColor);
24 }
25 this->onGetInvariantOutputColor(out);
26}
27
28void GrGeometryProcessor::getInvariantOutputCoverage(GrInitInvariantOutput* out) const {
29 this->onGetInvariantOutputCoverage(out);
30}
31
32///////////////////////////////////////////////////////////////////////////////////////////////////
33
34#include "gl/builders/GrGLProgramBuilder.h"
35
36void GrGLGeometryProcessor::setupColorPassThrough(GrGLGPBuilder* pb,
37 GrGPInput inputType,
38 const char* outputName,
39 const GrGeometryProcessor::GrAttribute* colorAttr,
40 UniformHandle* colorUniform) {
41 GrGLGPFragmentBuilder* fs = pb->getFragmentShaderBuilder();
42 if (kUniform_GrGPInput == inputType) {
43 SkASSERT(colorUniform);
44 const char* stagedLocalVarName;
45 *colorUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility,
46 kVec4f_GrSLType,
47 kDefault_GrSLPrecision,
48 "Color",
49 &stagedLocalVarName);
50 fs->codeAppendf("%s = %s;", outputName, stagedLocalVarName);
51 } else if (kAttribute_GrGPInput == inputType) {
52 SkASSERT(colorAttr);
53 pb->addPassThroughAttribute(colorAttr, outputName);
54 } else if (kAllOnes_GrGPInput == inputType) {
55 fs->codeAppendf("%s = vec4(1);", outputName);
56 }
57}
58
joshualittee2af952014-12-30 09:04:15 -080059void GrGLGeometryProcessor::addUniformViewMatrix(GrGLGPBuilder* pb) {
60 fViewMatrixUniform = pb->addUniform(GrGLProgramBuilder::kVertex_Visibility,
61 kMat33f_GrSLType, kDefault_GrSLPrecision,
62 "uViewM",
63 &fViewMatrixName);
64}
65
66void GrGLGeometryProcessor::setUniformViewMatrix(const GrGLProgramDataManager& pdman,
67 const SkMatrix& viewMatrix) {
68 if (!fViewMatrix.cheapEqualTo(viewMatrix)) {
69 SkASSERT(fViewMatrixUniform.isValid());
70 fViewMatrix = viewMatrix;
71
72 GrGLfloat viewMatrix[3 * 3];
73 GrGLGetMatrix<3>(viewMatrix, fViewMatrix);
74 pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
75 }
76}
77
joshualitt9b989322014-12-15 14:16:27 -080078///////////////////////////////////////////////////////////////////////////////////////////////////
79
80struct PathBatchTracker {
81 GrGPInput fInputColorType;
82 GrGPInput fInputCoverageType;
83 GrColor fColor;
joshualitt290c09b2014-12-19 13:45:20 -080084 bool fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -080085};
86
87class GrGLPathProcessor : public GrGLGeometryProcessor {
88public:
89 GrGLPathProcessor(const GrPathProcessor&, const GrBatchTracker&)
90 : fColor(GrColor_ILLEGAL) {}
91
92 void emitCode(const EmitArgs& args) SK_OVERRIDE {
93 GrGLGPBuilder* pb = args.fPB;
94 GrGLGPFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder();
95 const PathBatchTracker& local = args.fBT.cast<PathBatchTracker>();
96
97 // Setup uniform color
98 if (kUniform_GrGPInput == local.fInputColorType) {
99 const char* stagedLocalVarName;
100 fColorUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility,
101 kVec4f_GrSLType,
102 kDefault_GrSLPrecision,
103 "Color",
104 &stagedLocalVarName);
105 fs->codeAppendf("%s = %s;", args.fOutputColor, stagedLocalVarName);
106 }
107
108 // setup constant solid coverage
109 if (kAllOnes_GrGPInput == local.fInputCoverageType) {
110 fs->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
111 }
112 }
113
114 static inline void GenKey(const GrPathProcessor&,
115 const GrBatchTracker& bt,
116 const GrGLCaps&,
117 GrProcessorKeyBuilder* b) {
118 const PathBatchTracker& local = bt.cast<PathBatchTracker>();
119 b->add32(local.fInputColorType | local.fInputCoverageType << 16);
120 }
121
122 void setData(const GrGLProgramDataManager& pdman,
123 const GrPrimitiveProcessor& primProc,
124 const GrBatchTracker& bt) SK_OVERRIDE {
125 const PathBatchTracker& local = bt.cast<PathBatchTracker>();
126 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
127 GrGLfloat c[4];
128 GrColorToRGBAFloat(local.fColor, c);
129 pdman.set4fv(fColorUniform, 1, c);
130 fColor = local.fColor;
131 }
132 }
133
134private:
135 UniformHandle fColorUniform;
136 GrColor fColor;
137
138 typedef GrGLGeometryProcessor INHERITED;
139};
140
joshualitt8059eb92014-12-29 15:10:07 -0800141GrPathProcessor::GrPathProcessor(GrColor color,
142 const SkMatrix& viewMatrix,
143 const SkMatrix& localMatrix)
144 : INHERITED(viewMatrix, localMatrix)
joshualitt290c09b2014-12-19 13:45:20 -0800145 , fColor(color) {
joshualitt9b989322014-12-15 14:16:27 -0800146 this->initClassID<GrPathProcessor>();
147}
148
149void GrPathProcessor::getInvariantOutputColor(GrInitInvariantOutput* out) const {
150 out->setKnownFourComponents(fColor);
151}
152
153void GrPathProcessor::getInvariantOutputCoverage(GrInitInvariantOutput* out) const {
154 out->setKnownSingleComponent(0xff);
155}
156
157void GrPathProcessor::initBatchTracker(GrBatchTracker* bt, const InitBT& init) const {
158 PathBatchTracker* local = bt->cast<PathBatchTracker>();
159 if (init.fColorIgnored) {
160 local->fInputColorType = kIgnored_GrGPInput;
161 local->fColor = GrColor_ILLEGAL;
162 } else {
163 local->fInputColorType = kUniform_GrGPInput;
164 local->fColor = GrColor_ILLEGAL == init.fOverrideColor ? this->color() :
165 init.fOverrideColor;
166 }
167
168 local->fInputCoverageType = init.fCoverageIgnored ? kIgnored_GrGPInput : kAllOnes_GrGPInput;
joshualitt290c09b2014-12-19 13:45:20 -0800169 local->fUsesLocalCoords = init.fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800170}
171
172bool GrPathProcessor::canMakeEqual(const GrBatchTracker& m,
173 const GrPrimitiveProcessor& that,
174 const GrBatchTracker& t) const {
175 if (this->classID() != that.classID() || !this->hasSameTextureAccesses(that)) {
176 return false;
177 }
178
joshualitt8059eb92014-12-29 15:10:07 -0800179 if (!this->viewMatrix().cheapEqualTo(that.viewMatrix())) {
180 return false;
181 }
182
joshualitt9b989322014-12-15 14:16:27 -0800183 const PathBatchTracker& mine = m.cast<PathBatchTracker>();
184 const PathBatchTracker& theirs = t.cast<PathBatchTracker>();
joshualitt290c09b2014-12-19 13:45:20 -0800185 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
186 that, theirs.fUsesLocalCoords) &&
187 CanCombineOutput(mine.fInputColorType, mine.fColor,
joshualitt9b989322014-12-15 14:16:27 -0800188 theirs.fInputColorType, theirs.fColor) &&
189 CanCombineOutput(mine.fInputCoverageType, 0xff,
190 theirs.fInputCoverageType, 0xff);
191}
192
193void GrPathProcessor::getGLProcessorKey(const GrBatchTracker& bt,
194 const GrGLCaps& caps,
195 GrProcessorKeyBuilder* b) const {
196 GrGLPathProcessor::GenKey(*this, bt, caps, b);
197}
198
199GrGLGeometryProcessor* GrPathProcessor::createGLInstance(const GrBatchTracker& bt) const {
200 return SkNEW_ARGS(GrGLPathProcessor, (*this, bt));
201}