blob: d47f687d8970164f68ebf7629a011b9797a07c4d [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
59///////////////////////////////////////////////////////////////////////////////////////////////////
60
61struct PathBatchTracker {
62 GrGPInput fInputColorType;
63 GrGPInput fInputCoverageType;
64 GrColor fColor;
joshualitt290c09b2014-12-19 13:45:20 -080065 bool fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -080066};
67
68class GrGLPathProcessor : public GrGLGeometryProcessor {
69public:
70 GrGLPathProcessor(const GrPathProcessor&, const GrBatchTracker&)
71 : fColor(GrColor_ILLEGAL) {}
72
73 void emitCode(const EmitArgs& args) SK_OVERRIDE {
74 GrGLGPBuilder* pb = args.fPB;
75 GrGLGPFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder();
76 const PathBatchTracker& local = args.fBT.cast<PathBatchTracker>();
77
78 // Setup uniform color
79 if (kUniform_GrGPInput == local.fInputColorType) {
80 const char* stagedLocalVarName;
81 fColorUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility,
82 kVec4f_GrSLType,
83 kDefault_GrSLPrecision,
84 "Color",
85 &stagedLocalVarName);
86 fs->codeAppendf("%s = %s;", args.fOutputColor, stagedLocalVarName);
87 }
88
89 // setup constant solid coverage
90 if (kAllOnes_GrGPInput == local.fInputCoverageType) {
91 fs->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
92 }
93 }
94
95 static inline void GenKey(const GrPathProcessor&,
96 const GrBatchTracker& bt,
97 const GrGLCaps&,
98 GrProcessorKeyBuilder* b) {
99 const PathBatchTracker& local = bt.cast<PathBatchTracker>();
100 b->add32(local.fInputColorType | local.fInputCoverageType << 16);
101 }
102
103 void setData(const GrGLProgramDataManager& pdman,
104 const GrPrimitiveProcessor& primProc,
105 const GrBatchTracker& bt) SK_OVERRIDE {
106 const PathBatchTracker& local = bt.cast<PathBatchTracker>();
107 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
108 GrGLfloat c[4];
109 GrColorToRGBAFloat(local.fColor, c);
110 pdman.set4fv(fColorUniform, 1, c);
111 fColor = local.fColor;
112 }
113 }
114
115private:
116 UniformHandle fColorUniform;
117 GrColor fColor;
118
119 typedef GrGLGeometryProcessor INHERITED;
120};
121
joshualitt290c09b2014-12-19 13:45:20 -0800122GrPathProcessor::GrPathProcessor(GrColor color, const SkMatrix& localMatrix)
123 : INHERITED(localMatrix)
124 , fColor(color) {
joshualitt9b989322014-12-15 14:16:27 -0800125 this->initClassID<GrPathProcessor>();
126}
127
128void GrPathProcessor::getInvariantOutputColor(GrInitInvariantOutput* out) const {
129 out->setKnownFourComponents(fColor);
130}
131
132void GrPathProcessor::getInvariantOutputCoverage(GrInitInvariantOutput* out) const {
133 out->setKnownSingleComponent(0xff);
134}
135
136void GrPathProcessor::initBatchTracker(GrBatchTracker* bt, const InitBT& init) const {
137 PathBatchTracker* local = bt->cast<PathBatchTracker>();
138 if (init.fColorIgnored) {
139 local->fInputColorType = kIgnored_GrGPInput;
140 local->fColor = GrColor_ILLEGAL;
141 } else {
142 local->fInputColorType = kUniform_GrGPInput;
143 local->fColor = GrColor_ILLEGAL == init.fOverrideColor ? this->color() :
144 init.fOverrideColor;
145 }
146
147 local->fInputCoverageType = init.fCoverageIgnored ? kIgnored_GrGPInput : kAllOnes_GrGPInput;
joshualitt290c09b2014-12-19 13:45:20 -0800148 local->fUsesLocalCoords = init.fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800149}
150
151bool GrPathProcessor::canMakeEqual(const GrBatchTracker& m,
152 const GrPrimitiveProcessor& that,
153 const GrBatchTracker& t) const {
154 if (this->classID() != that.classID() || !this->hasSameTextureAccesses(that)) {
155 return false;
156 }
157
158 const PathBatchTracker& mine = m.cast<PathBatchTracker>();
159 const PathBatchTracker& theirs = t.cast<PathBatchTracker>();
joshualitt290c09b2014-12-19 13:45:20 -0800160 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
161 that, theirs.fUsesLocalCoords) &&
162 CanCombineOutput(mine.fInputColorType, mine.fColor,
joshualitt9b989322014-12-15 14:16:27 -0800163 theirs.fInputColorType, theirs.fColor) &&
164 CanCombineOutput(mine.fInputCoverageType, 0xff,
165 theirs.fInputCoverageType, 0xff);
166}
167
168void GrPathProcessor::getGLProcessorKey(const GrBatchTracker& bt,
169 const GrGLCaps& caps,
170 GrProcessorKeyBuilder* b) const {
171 GrGLPathProcessor::GenKey(*this, bt, caps, b);
172}
173
174GrGLGeometryProcessor* GrPathProcessor::createGLInstance(const GrBatchTracker& bt) const {
175 return SkNEW_ARGS(GrGLPathProcessor, (*this, bt));
176}