blob: 9d162ecaa4b5f05f6808bbf9a7be342f32ff0fd1 [file] [log] [blame]
bsalomon@google.com4fa66942011-09-20 19:06:12 +00001/*
2 * Copyright 2011 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
egdaniel0d3f0612015-10-21 10:45:48 -07008#ifndef GrGLSLShaderVar_DEFINED
9#define GrGLSLShaderVar_DEFINED
bsalomon@google.com4fa66942011-09-20 19:06:12 +000010
joshualitt249af152014-09-15 11:41:13 -070011#include "GrShaderVar.h"
egdanielf5294392015-10-21 07:14:17 -070012#include "../glsl/GrGLSL.h"
13#include "../glsl/GrGLSLCaps.h"
bsalomon@google.com4fa66942011-09-20 19:06:12 +000014
tomhudson@google.comda668982011-12-07 15:06:29 +000015#define USE_UNIFORM_FLOAT_ARRAYS true
16
bsalomon@google.com4fa66942011-09-20 19:06:12 +000017/**
18 * Represents a variable in a shader
19 */
egdaniel0d3f0612015-10-21 10:45:48 -070020class GrGLSLShaderVar : public GrShaderVar {
bsalomon@google.com4fa66942011-09-20 19:06:12 +000021public:
tomhudson@google.com086e5352011-12-08 14:44:10 +000022 /**
bsalomon@google.com4fa66942011-09-20 19:06:12 +000023 * Defaults to a float with no precision specifier
24 */
egdaniel0d3f0612015-10-21 10:45:48 -070025 GrGLSLShaderVar()
joshualitt249af152014-09-15 11:41:13 -070026 : GrShaderVar()
joshualitt249af152014-09-15 11:41:13 -070027 , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.com4fa66942011-09-20 19:06:12 +000028 }
29
egdaniel0d3f0612015-10-21 10:45:48 -070030 GrGLSLShaderVar(const char* name, GrSLType type, int arrayCount = kNonArray,
31 GrSLPrecision precision = kDefault_GrSLPrecision)
joshualitt249af152014-09-15 11:41:13 -070032 : GrShaderVar(name, type, arrayCount, precision)
joshualitt249af152014-09-15 11:41:13 -070033 , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000034 SkASSERT(kVoid_GrSLType != type);
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +000035 fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
joshualitt249af152014-09-15 11:41:13 -070036 }
37
egdaniel0d3f0612015-10-21 10:45:48 -070038 GrGLSLShaderVar(const char* name, GrSLType type, TypeModifier typeModifier,
39 int arrayCount = kNonArray, GrSLPrecision precision = kDefault_GrSLPrecision)
joshualitt249af152014-09-15 11:41:13 -070040 : GrShaderVar(name, type, typeModifier, arrayCount, precision)
joshualitt249af152014-09-15 11:41:13 -070041 , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS) {
42 SkASSERT(kVoid_GrSLType != type);
43 }
44
egdaniel0d3f0612015-10-21 10:45:48 -070045 GrGLSLShaderVar(const GrShaderVar& var)
joshualitt249af152014-09-15 11:41:13 -070046 : GrShaderVar(var)
joshualitt249af152014-09-15 11:41:13 -070047 , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS) {
48 SkASSERT(kVoid_GrSLType != var.getType());
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +000049 }
50
egdaniel0d3f0612015-10-21 10:45:48 -070051 GrGLSLShaderVar(const GrGLSLShaderVar& var)
joshualitt249af152014-09-15 11:41:13 -070052 : GrShaderVar(var.c_str(), var.getType(), var.getTypeModifier(),
53 var.getArrayCount(), var.getPrecision())
cdaltonc08f1962016-02-12 12:14:06 -080054 , fUseUniformFloatArrays(var.fUseUniformFloatArrays)
55 , fLayoutQualifier(var.fLayoutQualifier)
56 , fExtraModifiers(var.fExtraModifiers) {
joshualitt249af152014-09-15 11:41:13 -070057 SkASSERT(kVoid_GrSLType != var.getType());
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +000058 }
bsalomon@google.com4fa66942011-09-20 19:06:12 +000059
60 /**
61 * Values for array count that have special meaning. We allow 1-sized arrays.
62 */
63 enum {
64 kNonArray = 0, // not an array
65 kUnsizedArray = -1, // an unsized array (declared with [])
66 };
67
68 /**
69 * Sets as a non-array.
70 */
tomhudson@google.com168e6342012-04-18 17:49:20 +000071 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +000072 TypeModifier typeModifier,
bsalomon@google.comf0a104e2012-07-10 17:51:07 +000073 const SkString& name,
bsalomonc0bd6482014-12-09 10:04:14 -080074 GrSLPrecision precision = kDefault_GrSLPrecision,
egdanielae474182016-01-21 11:19:52 -080075 const char* layoutQualifier = nullptr,
cdaltonc08f1962016-02-12 12:14:06 -080076 const char* extraModifiers = nullptr,
tomhudson@google.comda668982011-12-07 15:06:29 +000077 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000078 SkASSERT(kVoid_GrSLType != type);
cdalton5f2d8e22016-03-11 13:34:32 -080079 SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeAcceptsPrecision(type));
robertphillips46d36f02015-01-18 08:14:14 -080080 INHERITED::set(type, name, typeModifier, precision);
egdanielae474182016-01-21 11:19:52 -080081 fLayoutQualifier = layoutQualifier;
cdaltonc08f1962016-02-12 12:14:06 -080082 if (extraModifiers) {
83 fExtraModifiers.printf("%s ", extraModifiers);
84 }
tomhudson@google.comda668982011-12-07 15:06:29 +000085 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000086 }
87
88 /**
89 * Sets as a non-array.
90 */
tomhudson@google.com168e6342012-04-18 17:49:20 +000091 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +000092 TypeModifier typeModifier,
bsalomon@google.com4fa66942011-09-20 19:06:12 +000093 const char* name,
bsalomonc0bd6482014-12-09 10:04:14 -080094 GrSLPrecision precision = kDefault_GrSLPrecision,
egdanielae474182016-01-21 11:19:52 -080095 const char* layoutQualifier = nullptr,
cdaltonc08f1962016-02-12 12:14:06 -080096 const char* extraModifiers = nullptr,
tomhudson@google.comda668982011-12-07 15:06:29 +000097 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000098 SkASSERT(kVoid_GrSLType != type);
cdalton5f2d8e22016-03-11 13:34:32 -080099 SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeAcceptsPrecision(type));
robertphillips46d36f02015-01-18 08:14:14 -0800100 INHERITED::set(type, name, typeModifier, precision);
egdanielae474182016-01-21 11:19:52 -0800101 fLayoutQualifier = layoutQualifier;
cdaltonc08f1962016-02-12 12:14:06 -0800102 if (extraModifiers) {
103 fExtraModifiers.printf("%s ", extraModifiers);
104 }
tomhudson@google.comda668982011-12-07 15:06:29 +0000105 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000106 }
107
108 /**
109 * Set all var options
110 */
tomhudson@google.com168e6342012-04-18 17:49:20 +0000111 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +0000112 TypeModifier typeModifier,
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000113 const SkString& name,
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000114 int count,
bsalomonc0bd6482014-12-09 10:04:14 -0800115 GrSLPrecision precision = kDefault_GrSLPrecision,
egdanielae474182016-01-21 11:19:52 -0800116 const char* layoutQualifier = nullptr,
cdaltonc08f1962016-02-12 12:14:06 -0800117 const char* extraModifiers = nullptr,
tomhudson@google.comda668982011-12-07 15:06:29 +0000118 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000119 SkASSERT(kVoid_GrSLType != type);
cdalton5f2d8e22016-03-11 13:34:32 -0800120 SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeAcceptsPrecision(type));
robertphillips46d36f02015-01-18 08:14:14 -0800121 INHERITED::set(type, name, typeModifier, precision, count);
egdanielae474182016-01-21 11:19:52 -0800122 fLayoutQualifier = layoutQualifier;
cdaltonc08f1962016-02-12 12:14:06 -0800123 if (extraModifiers) {
124 fExtraModifiers.printf("%s ", extraModifiers);
125 }
tomhudson@google.comda668982011-12-07 15:06:29 +0000126 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000127 }
128
129 /**
130 * Set all var options
131 */
tomhudson@google.com168e6342012-04-18 17:49:20 +0000132 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +0000133 TypeModifier typeModifier,
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000134 const char* name,
135 int count,
bsalomonc0bd6482014-12-09 10:04:14 -0800136 GrSLPrecision precision = kDefault_GrSLPrecision,
egdanielae474182016-01-21 11:19:52 -0800137 const char* layoutQualifier = nullptr,
cdaltonc08f1962016-02-12 12:14:06 -0800138 const char* extraModifiers = nullptr,
tomhudson@google.comda668982011-12-07 15:06:29 +0000139 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000140 SkASSERT(kVoid_GrSLType != type);
cdalton5f2d8e22016-03-11 13:34:32 -0800141 SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeAcceptsPrecision(type));
robertphillips46d36f02015-01-18 08:14:14 -0800142 INHERITED::set(type, name, typeModifier, precision, count);
egdanielae474182016-01-21 11:19:52 -0800143 fLayoutQualifier = layoutQualifier;
cdaltonc08f1962016-02-12 12:14:06 -0800144 if (extraModifiers) {
145 fExtraModifiers.printf("%s ", extraModifiers);
146 }
tomhudson@google.comda668982011-12-07 15:06:29 +0000147 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000148 }
149
150 /**
egdaniel07caf562016-01-21 15:21:48 -0800151 * Set the layout qualifier
152 */
153 void setLayoutQualifier(const char* layoutQualifier) {
154 fLayoutQualifier = layoutQualifier;
155 }
156
cdaltonc08f1962016-02-12 12:14:06 -0800157 void addModifier(const char* modifier) {
158 if (modifier) {
159 fExtraModifiers.appendf("%s ", modifier);
160 }
161 }
162
egdaniel07caf562016-01-21 15:21:48 -0800163 /**
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000164 * Write a declaration of this variable to out.
165 */
egdanielf5294392015-10-21 07:14:17 -0700166 void appendDecl(const GrGLSLCaps* glslCaps, SkString* out) const {
cdalton5f2d8e22016-03-11 13:34:32 -0800167 SkASSERT(kDefault_GrSLPrecision == fPrecision || GrSLTypeAcceptsPrecision(fType));
egdanielae474182016-01-21 11:19:52 -0800168 if (!fLayoutQualifier.isEmpty()) {
169 out->appendf("layout(%s) ", fLayoutQualifier.c_str());
bsalomon@google.com5fa21072012-10-25 14:57:46 +0000170 }
cdaltonc08f1962016-02-12 12:14:06 -0800171 out->append(fExtraModifiers);
tomhudson@google.com086e5352011-12-08 14:44:10 +0000172 if (this->getTypeModifier() != kNone_TypeModifier) {
ethannicholas22793252016-01-30 09:59:10 -0800173 out->append(TypeModifierString(glslCaps, this->getTypeModifier()));
174 out->append(" ");
tomhudson@google.com086e5352011-12-08 14:44:10 +0000175 }
tomhudson@google.com168e6342012-04-18 17:49:20 +0000176 GrSLType effectiveType = this->getType();
cdalton1f50acf2016-04-11 11:30:50 -0700177 if (glslCaps->usesPrecisionModifiers() && GrSLTypeAcceptsPrecision(effectiveType)) {
178 // Desktop GLSL has added precision qualifiers but they don't do anything.
179 out->appendf("%s ", GrGLSLPrecisionString(fPrecision));
ethannicholas22793252016-01-30 09:59:10 -0800180 }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000181 if (this->isArray()) {
182 if (this->isUnsizedArray()) {
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000183 out->appendf("%s %s[]",
bsalomon@google.com018f1792013-04-18 19:36:09 +0000184 GrGLSLTypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000185 this->getName().c_str());
186 } else {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000187 SkASSERT(this->getArrayCount() > 0);
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000188 out->appendf("%s %s[%d]",
bsalomon@google.com018f1792013-04-18 19:36:09 +0000189 GrGLSLTypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000190 this->getName().c_str(),
191 this->getArrayCount());
192 }
193 } else {
194 out->appendf("%s %s",
bsalomon@google.com018f1792013-04-18 19:36:09 +0000195 GrGLSLTypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000196 this->getName().c_str());
197 }
198 }
199
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000200 void appendArrayAccess(int index, SkString* out) const {
tomhudson@google.comda668982011-12-07 15:06:29 +0000201 out->appendf("%s[%d]%s",
202 this->getName().c_str(),
203 index,
204 fUseUniformFloatArrays ? "" : ".x");
205 }
206
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000207 void appendArrayAccess(const char* indexName, SkString* out) const {
tomhudson@google.comda668982011-12-07 15:06:29 +0000208 out->appendf("%s[%s]%s",
209 this->getName().c_str(),
210 indexName,
211 fUseUniformFloatArrays ? "" : ".x");
212 }
213
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000214private:
egdanielf5294392015-10-21 07:14:17 -0700215 static const char* TypeModifierString(const GrGLSLCaps* glslCaps, TypeModifier t) {
jvanverth9df16b52016-10-11 10:03:56 -0700216 GrGLSLGeneration gen = glslCaps->generation();
tomhudson@google.com086e5352011-12-08 14:44:10 +0000217 switch (t) {
218 case kNone_TypeModifier:
219 return "";
tomhudson@google.com086e5352011-12-08 14:44:10 +0000220 case kIn_TypeModifier:
bsalomon@google.com77cf4602013-04-22 21:05:48 +0000221 return "in";
222 case kInOut_TypeModifier:
223 return "inout";
224 case kOut_TypeModifier:
225 return "out";
tomhudson@google.com086e5352011-12-08 14:44:10 +0000226 case kUniform_TypeModifier:
227 return "uniform";
jvanverth9df16b52016-10-11 10:03:56 -0700228 case kAttribute_TypeModifier:
229 return k110_GrGLSLGeneration == gen ? "attribute" : "in";
230 case kVaryingIn_TypeModifier:
231 return k110_GrGLSLGeneration == gen ? "varying" : "in";
232 case kVaryingOut_TypeModifier:
233 return k110_GrGLSLGeneration == gen ? "varying" : "out";
tomhudson@google.com086e5352011-12-08 14:44:10 +0000234 default:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000235 SkFAIL("Unknown shader variable type modifier.");
tomhudson@google.com086e5352011-12-08 14:44:10 +0000236 return ""; // suppress warning
237 }
238 }
239
tomhudson@google.comda668982011-12-07 15:06:29 +0000240 /// Work around driver bugs on some hardware that don't correctly
241 /// support uniform float []
cdaltonc08f1962016-02-12 12:14:06 -0800242 bool fUseUniformFloatArrays;
joshualitt249af152014-09-15 11:41:13 -0700243
cdaltonc08f1962016-02-12 12:14:06 -0800244 SkString fLayoutQualifier;
245 SkString fExtraModifiers;
egdanielae474182016-01-21 11:19:52 -0800246
joshualitt249af152014-09-15 11:41:13 -0700247 typedef GrShaderVar INHERITED;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000248};
249
250#endif