blob: 6b9d2c2aebfd30f4d707e6386f41d4687ab57e8f [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) {
joshualitt03d3bb02014-12-05 12:14:43 -080025 return SkNEW_ARGS(DefaultGeoProc, (gpTypeFlags));
joshualitt4973d9d2014-11-08 09:24:25 -080026 }
27
joshualitteb2a6762014-12-04 11:35:33 -080028 virtual const char* name() const SK_OVERRIDE { return "DefaultGeometryProcessor"; }
joshualitt4973d9d2014-11-08 09:24:25 -080029
joshualitt2dd1ae02014-12-03 06:24:10 -080030 const GrAttribute* inPosition() const { return fInPosition; }
31 const GrAttribute* inColor() const { return fInColor; }
32 const GrAttribute* inLocalCoords() const { return fInLocalCoords; }
33 const GrAttribute* inCoverage() const { return fInCoverage; }
34
joshualitt4973d9d2014-11-08 09:24:25 -080035 class GLProcessor : public GrGLGeometryProcessor {
36 public:
joshualitteb2a6762014-12-04 11:35:33 -080037 GLProcessor(const GrGeometryProcessor&,
38 const GrBatchTracker&) {}
joshualitt4973d9d2014-11-08 09:24:25 -080039
40 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
joshualitt2dd1ae02014-12-03 06:24:10 -080041 const DefaultGeoProc& gp = args.fGP.cast<DefaultGeoProc>();
joshualitt4973d9d2014-11-08 09:24:25 -080042 GrGLVertexBuilder* vs = args.fPB->getVertexShaderBuilder();
43
joshualitt2dd1ae02014-12-03 06:24:10 -080044 vs->codeAppendf("%s = %s;", vs->positionCoords(), gp.inPosition()->fName);
45
46 // Setup pass through color
47 if (gp.inColor()) {
48 args.fPB->addPassThroughAttribute(gp.inColor(), args.fOutputColor);
49 }
50
51 // Setup local coords if needed
52 if (gp.inLocalCoords()) {
53 vs->codeAppendf("%s = %s;", vs->localCoords(), gp.inLocalCoords()->fName);
54 } else {
55 vs->codeAppendf("%s = %s;", vs->localCoords(), gp.inPosition()->fName);
56 }
57
joshualitt4973d9d2014-11-08 09:24:25 -080058 // setup position varying
59 vs->codeAppendf("%s = %s * vec3(%s, 1);", vs->glPosition(), vs->uViewM(),
joshualitt2dd1ae02014-12-03 06:24:10 -080060 gp.inPosition()->fName);
joshualitt4973d9d2014-11-08 09:24:25 -080061
joshualitt2dd1ae02014-12-03 06:24:10 -080062 // Setup coverage as pass through
joshualitt4973d9d2014-11-08 09:24:25 -080063 GrGLGPFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder();
joshualitt2dd1ae02014-12-03 06:24:10 -080064 fs->codeAppendf("float alpha = 1.0;");
65 if (gp.inCoverage()) {
66 args.fPB->addPassThroughAttribute(gp.inCoverage(), "alpha");
67 }
68 fs->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage);
joshualitt4973d9d2014-11-08 09:24:25 -080069 }
70
joshualitt87f48d92014-12-04 10:41:40 -080071 static inline void GenKey(const GrGeometryProcessor& gp,
72 const GrBatchTracker&,
73 const GrGLCaps&,
74 GrProcessorKeyBuilder* b) {
joshualitt2dd1ae02014-12-03 06:24:10 -080075 const DefaultGeoProc& def = gp.cast<DefaultGeoProc>();
76 b->add32(def.fFlags);
77 }
joshualitt4973d9d2014-11-08 09:24:25 -080078
joshualitt87f48d92014-12-04 10:41:40 -080079 virtual void setData(const GrGLProgramDataManager&,
80 const GrGeometryProcessor&,
81 const GrBatchTracker&) SK_OVERRIDE {}
joshualitt4973d9d2014-11-08 09:24:25 -080082
83 private:
84 typedef GrGLGeometryProcessor INHERITED;
85 };
86
joshualitteb2a6762014-12-04 11:35:33 -080087 virtual void getGLProcessorKey(const GrBatchTracker& bt,
88 const GrGLCaps& caps,
89 GrProcessorKeyBuilder* b) const SK_OVERRIDE {
90 GLProcessor::GenKey(*this, bt, caps, b);
91 }
92
93 virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE {
94 return SkNEW_ARGS(GLProcessor, (*this, bt));
95 }
96
joshualitt4973d9d2014-11-08 09:24:25 -080097private:
joshualitt2dd1ae02014-12-03 06:24:10 -080098 DefaultGeoProc(uint32_t gpTypeFlags)
99 : fInPosition(NULL)
100 , fInColor(NULL)
101 , fInLocalCoords(NULL)
102 , fInCoverage(NULL)
103 , fFlags(gpTypeFlags) {
joshualitteb2a6762014-12-04 11:35:33 -0800104 this->initClassID<DefaultGeoProc>();
joshualitt2dd1ae02014-12-03 06:24:10 -0800105 bool hasColor = SkToBool(gpTypeFlags & GrDefaultGeoProcFactory::kColor_GPType);
106 bool hasLocalCoord = SkToBool(gpTypeFlags & GrDefaultGeoProcFactory::kLocalCoord_GPType);
107 bool hasCoverage = SkToBool(gpTypeFlags & GrDefaultGeoProcFactory::kCoverage_GPType);
108 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
109 if (hasColor) {
110 fInColor = &this->addVertexAttrib(GrAttribute("inColor", kVec4ub_GrVertexAttribType));
111 this->setHasVertexColor();
112 }
113 if (hasLocalCoord) {
114 fInLocalCoords = &this->addVertexAttrib(GrAttribute("inLocalCoord",
115 kVec2f_GrVertexAttribType));
116 this->setHasLocalCoords();
117 }
118 if (hasCoverage) {
119 fInCoverage = &this->addVertexAttrib(GrAttribute("inCoverage",
120 kFloat_GrVertexAttribType));
121 this->setHasVertexCoverage();
122 }
123 }
joshualitt4973d9d2014-11-08 09:24:25 -0800124
125 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE {
joshualitt2dd1ae02014-12-03 06:24:10 -0800126 const DefaultGeoProc& gp = other.cast<DefaultGeoProc>();
127 return gp.fFlags == this->fFlags;
joshualitt4973d9d2014-11-08 09:24:25 -0800128 }
129
egdaniel605dd0f2014-11-12 08:35:25 -0800130 virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
joshualitt2dd1ae02014-12-03 06:24:10 -0800131 if (fInCoverage) {
joshualitt5478d422014-11-14 16:00:38 -0800132 inout->mulByUnknownAlpha();
133 } else {
134 inout->mulByKnownAlpha(255);
135 }
joshualitt4973d9d2014-11-08 09:24:25 -0800136 }
137
joshualitt2dd1ae02014-12-03 06:24:10 -0800138 const GrAttribute* fInPosition;
139 const GrAttribute* fInColor;
140 const GrAttribute* fInLocalCoords;
141 const GrAttribute* fInCoverage;
142 uint32_t fFlags;
joshualitt4973d9d2014-11-08 09:24:25 -0800143
joshualitt2dd1ae02014-12-03 06:24:10 -0800144 GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
joshualitt5478d422014-11-14 16:00:38 -0800145
joshualitt4973d9d2014-11-08 09:24:25 -0800146 typedef GrFragmentProcessor INHERITED;
147};
148
149GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DefaultGeoProc);
150
151GrGeometryProcessor* DefaultGeoProc::TestCreate(SkRandom* random,
152 GrContext*,
153 const GrDrawTargetCaps& caps,
154 GrTexture*[]) {
joshualitt2dd1ae02014-12-03 06:24:10 -0800155 uint32_t flags = 0;
156 if (random->nextBool()) {
157 flags |= GrDefaultGeoProcFactory::kColor_GPType;
joshualitt4973d9d2014-11-08 09:24:25 -0800158 }
joshualitt2dd1ae02014-12-03 06:24:10 -0800159 if (random->nextBool()) {
160 flags |= GrDefaultGeoProcFactory::kCoverage_GPType;
joshualitt4973d9d2014-11-08 09:24:25 -0800161 }
joshualitt2dd1ae02014-12-03 06:24:10 -0800162 if (random->nextBool()) {
163 flags |= GrDefaultGeoProcFactory::kLocalCoord_GPType;
164 }
165
166 return DefaultGeoProc::Create(flags);
joshualitt4973d9d2014-11-08 09:24:25 -0800167}
168
joshualitt2dd1ae02014-12-03 06:24:10 -0800169const GrGeometryProcessor* GrDefaultGeoProcFactory::Create(uint32_t gpTypeFlags) {
170 return DefaultGeoProc::Create(gpTypeFlags);
joshualitt4973d9d2014-11-08 09:24:25 -0800171}