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