blob: 0df519dd8f7450e662ec63af903a94fb28e1bfc8 [file] [log] [blame]
joshualitt4973d9d2014-11-08 09:24:25 -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 "GrDefaultGeoProcFactory.h"
9
joshualitt4973d9d2014-11-08 09:24:25 -080010#include "GrDrawState.h"
egdaniel605dd0f2014-11-12 08:35:25 -080011#include "GrInvariantOutput.h"
joshualitt2dd1ae02014-12-03 06:24:10 -080012#include "gl/GrGLGeometryProcessor.h"
13#include "gl/builders/GrGLProgramBuilder.h"
joshualitt4973d9d2014-11-08 09:24:25 -080014
15/*
16 * The default Geometry Processor simply takes position and multiplies it by the uniform view
17 * matrix. It also leaves coverage untouched. Behind the scenes, we may add per vertex color or
18 * local coords.
19 */
joshualitt2dd1ae02014-12-03 06:24:10 -080020typedef GrDefaultGeoProcFactory Flag;
21
joshualitt4973d9d2014-11-08 09:24:25 -080022class DefaultGeoProc : public GrGeometryProcessor {
23public:
joshualitt2dd1ae02014-12-03 06:24:10 -080024 static GrGeometryProcessor* Create(uint32_t gpTypeFlags) {
25 switch (gpTypeFlags) {
26 case Flag::kColor_GPType | Flag::kCoverage_GPType | Flag::kLocalCoord_GPType: {
27 GR_CREATE_STATIC_PROCESSOR(gDefaultGeoProcColLocCov, DefaultGeoProc, (gpTypeFlags));
28 return SkRef(gDefaultGeoProcColLocCov);
29 }
30 case Flag::kColor_GPType | Flag::kLocalCoord_GPType: {
31 GR_CREATE_STATIC_PROCESSOR(gDefaultGeoProcColLoc, DefaultGeoProc, (gpTypeFlags));
32 return SkRef(gDefaultGeoProcColLoc);
33 }
34 case Flag::kColor_GPType | Flag::kCoverage_GPType: {
35 GR_CREATE_STATIC_PROCESSOR(gDefaultGeoProcColCov, DefaultGeoProc, (gpTypeFlags));
36 return SkRef(gDefaultGeoProcColCov);
37 }
38 case Flag::kColor_GPType: {
39 GR_CREATE_STATIC_PROCESSOR(gDefaultGeoProcCol, DefaultGeoProc, (gpTypeFlags));
40 return SkRef(gDefaultGeoProcCol);
41 }
42 case Flag::kLocalCoord_GPType | Flag::kCoverage_GPType: {
43 GR_CREATE_STATIC_PROCESSOR(gDefaultGeoProcLocCov, DefaultGeoProc, (gpTypeFlags));
44 return SkRef(gDefaultGeoProcLocCov);
45 }
46 case Flag::kLocalCoord_GPType: {
47 GR_CREATE_STATIC_PROCESSOR(gDefaultGeoProcLoc, DefaultGeoProc, (gpTypeFlags));
48 return SkRef(gDefaultGeoProcLoc);
49 }
50 case Flag::kCoverage_GPType: {
51 GR_CREATE_STATIC_PROCESSOR(gDefaultGeoProcCov, DefaultGeoProc, (gpTypeFlags));
52 return SkRef(gDefaultGeoProcCov);
53 }
54 case Flag::kPosition_GPType: {
55 GR_CREATE_STATIC_PROCESSOR(gDefaultGeoProc, DefaultGeoProc, (gpTypeFlags));
56 return SkRef(gDefaultGeoProc);
57 }
58 default:
59 SkFAIL("Incomplete Switch");
60 return NULL;
61 }
joshualitt4973d9d2014-11-08 09:24:25 -080062 }
63
joshualitteb2a6762014-12-04 11:35:33 -080064 virtual const char* name() const SK_OVERRIDE { return "DefaultGeometryProcessor"; }
joshualitt4973d9d2014-11-08 09:24:25 -080065
joshualitt2dd1ae02014-12-03 06:24:10 -080066 const GrAttribute* inPosition() const { return fInPosition; }
67 const GrAttribute* inColor() const { return fInColor; }
68 const GrAttribute* inLocalCoords() const { return fInLocalCoords; }
69 const GrAttribute* inCoverage() const { return fInCoverage; }
70
joshualitt4973d9d2014-11-08 09:24:25 -080071 class GLProcessor : public GrGLGeometryProcessor {
72 public:
joshualitteb2a6762014-12-04 11:35:33 -080073 GLProcessor(const GrGeometryProcessor&,
74 const GrBatchTracker&) {}
joshualitt4973d9d2014-11-08 09:24:25 -080075
76 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
joshualitt2dd1ae02014-12-03 06:24:10 -080077 const DefaultGeoProc& gp = args.fGP.cast<DefaultGeoProc>();
joshualitt4973d9d2014-11-08 09:24:25 -080078 GrGLVertexBuilder* vs = args.fPB->getVertexShaderBuilder();
79
joshualitt2dd1ae02014-12-03 06:24:10 -080080 vs->codeAppendf("%s = %s;", vs->positionCoords(), gp.inPosition()->fName);
81
82 // Setup pass through color
83 if (gp.inColor()) {
84 args.fPB->addPassThroughAttribute(gp.inColor(), args.fOutputColor);
85 }
86
87 // Setup local coords if needed
88 if (gp.inLocalCoords()) {
89 vs->codeAppendf("%s = %s;", vs->localCoords(), gp.inLocalCoords()->fName);
90 } else {
91 vs->codeAppendf("%s = %s;", vs->localCoords(), gp.inPosition()->fName);
92 }
93
joshualitt4973d9d2014-11-08 09:24:25 -080094 // setup position varying
95 vs->codeAppendf("%s = %s * vec3(%s, 1);", vs->glPosition(), vs->uViewM(),
joshualitt2dd1ae02014-12-03 06:24:10 -080096 gp.inPosition()->fName);
joshualitt4973d9d2014-11-08 09:24:25 -080097
joshualitt2dd1ae02014-12-03 06:24:10 -080098 // Setup coverage as pass through
joshualitt4973d9d2014-11-08 09:24:25 -080099 GrGLGPFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder();
joshualitt2dd1ae02014-12-03 06:24:10 -0800100 fs->codeAppendf("float alpha = 1.0;");
101 if (gp.inCoverage()) {
102 args.fPB->addPassThroughAttribute(gp.inCoverage(), "alpha");
103 }
104 fs->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage);
joshualitt4973d9d2014-11-08 09:24:25 -0800105 }
106
joshualitt87f48d92014-12-04 10:41:40 -0800107 static inline void GenKey(const GrGeometryProcessor& gp,
108 const GrBatchTracker&,
109 const GrGLCaps&,
110 GrProcessorKeyBuilder* b) {
joshualitt2dd1ae02014-12-03 06:24:10 -0800111 const DefaultGeoProc& def = gp.cast<DefaultGeoProc>();
112 b->add32(def.fFlags);
113 }
joshualitt4973d9d2014-11-08 09:24:25 -0800114
joshualitt87f48d92014-12-04 10:41:40 -0800115 virtual void setData(const GrGLProgramDataManager&,
116 const GrGeometryProcessor&,
117 const GrBatchTracker&) SK_OVERRIDE {}
joshualitt4973d9d2014-11-08 09:24:25 -0800118
119 private:
120 typedef GrGLGeometryProcessor INHERITED;
121 };
122
joshualitteb2a6762014-12-04 11:35:33 -0800123 virtual void getGLProcessorKey(const GrBatchTracker& bt,
124 const GrGLCaps& caps,
125 GrProcessorKeyBuilder* b) const SK_OVERRIDE {
126 GLProcessor::GenKey(*this, bt, caps, b);
127 }
128
129 virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE {
130 return SkNEW_ARGS(GLProcessor, (*this, bt));
131 }
132
joshualitt4973d9d2014-11-08 09:24:25 -0800133private:
joshualitt2dd1ae02014-12-03 06:24:10 -0800134 DefaultGeoProc(uint32_t gpTypeFlags)
135 : fInPosition(NULL)
136 , fInColor(NULL)
137 , fInLocalCoords(NULL)
138 , fInCoverage(NULL)
139 , fFlags(gpTypeFlags) {
joshualitteb2a6762014-12-04 11:35:33 -0800140 this->initClassID<DefaultGeoProc>();
joshualitt2dd1ae02014-12-03 06:24:10 -0800141 bool hasColor = SkToBool(gpTypeFlags & GrDefaultGeoProcFactory::kColor_GPType);
142 bool hasLocalCoord = SkToBool(gpTypeFlags & GrDefaultGeoProcFactory::kLocalCoord_GPType);
143 bool hasCoverage = SkToBool(gpTypeFlags & GrDefaultGeoProcFactory::kCoverage_GPType);
144 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
145 if (hasColor) {
146 fInColor = &this->addVertexAttrib(GrAttribute("inColor", kVec4ub_GrVertexAttribType));
147 this->setHasVertexColor();
148 }
149 if (hasLocalCoord) {
150 fInLocalCoords = &this->addVertexAttrib(GrAttribute("inLocalCoord",
151 kVec2f_GrVertexAttribType));
152 this->setHasLocalCoords();
153 }
154 if (hasCoverage) {
155 fInCoverage = &this->addVertexAttrib(GrAttribute("inCoverage",
156 kFloat_GrVertexAttribType));
157 this->setHasVertexCoverage();
158 }
159 }
joshualitt4973d9d2014-11-08 09:24:25 -0800160
161 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE {
joshualitt2dd1ae02014-12-03 06:24:10 -0800162 const DefaultGeoProc& gp = other.cast<DefaultGeoProc>();
163 return gp.fFlags == this->fFlags;
joshualitt4973d9d2014-11-08 09:24:25 -0800164 }
165
egdaniel605dd0f2014-11-12 08:35:25 -0800166 virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
joshualitt2dd1ae02014-12-03 06:24:10 -0800167 if (fInCoverage) {
joshualitt5478d422014-11-14 16:00:38 -0800168 inout->mulByUnknownAlpha();
169 } else {
170 inout->mulByKnownAlpha(255);
171 }
joshualitt4973d9d2014-11-08 09:24:25 -0800172 }
173
joshualitt2dd1ae02014-12-03 06:24:10 -0800174 const GrAttribute* fInPosition;
175 const GrAttribute* fInColor;
176 const GrAttribute* fInLocalCoords;
177 const GrAttribute* fInCoverage;
178 uint32_t fFlags;
joshualitt4973d9d2014-11-08 09:24:25 -0800179
joshualitt2dd1ae02014-12-03 06:24:10 -0800180 GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
joshualitt5478d422014-11-14 16:00:38 -0800181
joshualitt4973d9d2014-11-08 09:24:25 -0800182 typedef GrFragmentProcessor INHERITED;
183};
184
185GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DefaultGeoProc);
186
187GrGeometryProcessor* DefaultGeoProc::TestCreate(SkRandom* random,
188 GrContext*,
189 const GrDrawTargetCaps& caps,
190 GrTexture*[]) {
joshualitt2dd1ae02014-12-03 06:24:10 -0800191 uint32_t flags = 0;
192 if (random->nextBool()) {
193 flags |= GrDefaultGeoProcFactory::kColor_GPType;
joshualitt4973d9d2014-11-08 09:24:25 -0800194 }
joshualitt2dd1ae02014-12-03 06:24:10 -0800195 if (random->nextBool()) {
196 flags |= GrDefaultGeoProcFactory::kCoverage_GPType;
joshualitt4973d9d2014-11-08 09:24:25 -0800197 }
joshualitt2dd1ae02014-12-03 06:24:10 -0800198 if (random->nextBool()) {
199 flags |= GrDefaultGeoProcFactory::kLocalCoord_GPType;
200 }
201
202 return DefaultGeoProc::Create(flags);
joshualitt4973d9d2014-11-08 09:24:25 -0800203}
204
joshualitt2dd1ae02014-12-03 06:24:10 -0800205const GrGeometryProcessor* GrDefaultGeoProcFactory::Create(uint32_t gpTypeFlags) {
206 return DefaultGeoProc::Create(gpTypeFlags);
joshualitt4973d9d2014-11-08 09:24:25 -0800207}