blob: e26a75c0966794143980f48a66b7755f823bd806 [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())
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +000054 , fUseUniformFloatArrays(var.fUseUniformFloatArrays) {
joshualitt249af152014-09-15 11:41:13 -070055 SkASSERT(kVoid_GrSLType != var.getType());
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +000056 }
bsalomon@google.com4fa66942011-09-20 19:06:12 +000057
58 /**
59 * Values for array count that have special meaning. We allow 1-sized arrays.
60 */
61 enum {
62 kNonArray = 0, // not an array
63 kUnsizedArray = -1, // an unsized array (declared with [])
64 };
65
66 /**
67 * Sets as a non-array.
68 */
tomhudson@google.com168e6342012-04-18 17:49:20 +000069 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +000070 TypeModifier typeModifier,
bsalomon@google.comf0a104e2012-07-10 17:51:07 +000071 const SkString& name,
bsalomonc0bd6482014-12-09 10:04:14 -080072 GrSLPrecision precision = kDefault_GrSLPrecision,
egdanielae474182016-01-21 11:19:52 -080073 const char* layoutQualifier = nullptr,
tomhudson@google.comda668982011-12-07 15:06:29 +000074 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000075 SkASSERT(kVoid_GrSLType != type);
ethannicholas22793252016-01-30 09:59:10 -080076 SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeIsNumeric(type));
robertphillips46d36f02015-01-18 08:14:14 -080077 INHERITED::set(type, name, typeModifier, precision);
egdanielae474182016-01-21 11:19:52 -080078 fLayoutQualifier = layoutQualifier;
tomhudson@google.comda668982011-12-07 15:06:29 +000079 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000080 }
81
82 /**
83 * Sets as a non-array.
84 */
tomhudson@google.com168e6342012-04-18 17:49:20 +000085 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +000086 TypeModifier typeModifier,
bsalomon@google.com4fa66942011-09-20 19:06:12 +000087 const char* name,
bsalomonc0bd6482014-12-09 10:04:14 -080088 GrSLPrecision precision = kDefault_GrSLPrecision,
egdanielae474182016-01-21 11:19:52 -080089 const char* layoutQualifier = nullptr,
tomhudson@google.comda668982011-12-07 15:06:29 +000090 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000091 SkASSERT(kVoid_GrSLType != type);
ethannicholas22793252016-01-30 09:59:10 -080092 SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeIsNumeric(type));
robertphillips46d36f02015-01-18 08:14:14 -080093 INHERITED::set(type, name, typeModifier, precision);
egdanielae474182016-01-21 11:19:52 -080094 fLayoutQualifier = layoutQualifier;
tomhudson@google.comda668982011-12-07 15:06:29 +000095 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000096 }
97
98 /**
99 * Set all var options
100 */
tomhudson@google.com168e6342012-04-18 17:49:20 +0000101 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +0000102 TypeModifier typeModifier,
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000103 const SkString& name,
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000104 int count,
bsalomonc0bd6482014-12-09 10:04:14 -0800105 GrSLPrecision precision = kDefault_GrSLPrecision,
egdanielae474182016-01-21 11:19:52 -0800106 const char* layoutQualifier = nullptr,
tomhudson@google.comda668982011-12-07 15:06:29 +0000107 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000108 SkASSERT(kVoid_GrSLType != type);
ethannicholas22793252016-01-30 09:59:10 -0800109 SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeIsNumeric(type));
robertphillips46d36f02015-01-18 08:14:14 -0800110 INHERITED::set(type, name, typeModifier, precision, count);
egdanielae474182016-01-21 11:19:52 -0800111 fLayoutQualifier = layoutQualifier;
tomhudson@google.comda668982011-12-07 15:06:29 +0000112 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000113 }
114
115 /**
116 * Set all var options
117 */
tomhudson@google.com168e6342012-04-18 17:49:20 +0000118 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +0000119 TypeModifier typeModifier,
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000120 const char* name,
121 int count,
bsalomonc0bd6482014-12-09 10:04:14 -0800122 GrSLPrecision precision = kDefault_GrSLPrecision,
egdanielae474182016-01-21 11:19:52 -0800123 const char* layoutQualifier = nullptr,
tomhudson@google.comda668982011-12-07 15:06:29 +0000124 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000125 SkASSERT(kVoid_GrSLType != type);
ethannicholas22793252016-01-30 09:59:10 -0800126 SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeIsNumeric(type));
robertphillips46d36f02015-01-18 08:14:14 -0800127 INHERITED::set(type, name, typeModifier, precision, count);
egdanielae474182016-01-21 11:19:52 -0800128 fLayoutQualifier = layoutQualifier;
tomhudson@google.comda668982011-12-07 15:06:29 +0000129 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000130 }
131
132 /**
egdaniel07caf562016-01-21 15:21:48 -0800133 * Set the layout qualifier
134 */
135 void setLayoutQualifier(const char* layoutQualifier) {
136 fLayoutQualifier = layoutQualifier;
137 }
138
139 /**
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000140 * Write a declaration of this variable to out.
141 */
egdanielf5294392015-10-21 07:14:17 -0700142 void appendDecl(const GrGLSLCaps* glslCaps, SkString* out) const {
ethannicholas22793252016-01-30 09:59:10 -0800143 SkASSERT(kDefault_GrSLPrecision == fPrecision || GrSLTypeIsNumeric(fType));
egdanielae474182016-01-21 11:19:52 -0800144 if (!fLayoutQualifier.isEmpty()) {
145 out->appendf("layout(%s) ", fLayoutQualifier.c_str());
bsalomon@google.com5fa21072012-10-25 14:57:46 +0000146 }
tomhudson@google.com086e5352011-12-08 14:44:10 +0000147 if (this->getTypeModifier() != kNone_TypeModifier) {
ethannicholas22793252016-01-30 09:59:10 -0800148 if (GrSLTypeIsIntType(fType) && (this->getTypeModifier() == kVaryingIn_TypeModifier ||
149 this->getTypeModifier() == kVaryingOut_TypeModifier)) {
150 out->append("flat ");
151 }
152 out->append(TypeModifierString(glslCaps, this->getTypeModifier()));
153 out->append(" ");
tomhudson@google.com086e5352011-12-08 14:44:10 +0000154 }
tomhudson@google.com168e6342012-04-18 17:49:20 +0000155 GrSLType effectiveType = this->getType();
ethannicholas22793252016-01-30 09:59:10 -0800156 if (effectiveType != kBool_GrSLType) {
157 out->append(PrecisionString(glslCaps, fPrecision));
158 }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000159 if (this->isArray()) {
160 if (this->isUnsizedArray()) {
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000161 out->appendf("%s %s[]",
bsalomon@google.com018f1792013-04-18 19:36:09 +0000162 GrGLSLTypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000163 this->getName().c_str());
164 } else {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000165 SkASSERT(this->getArrayCount() > 0);
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000166 out->appendf("%s %s[%d]",
bsalomon@google.com018f1792013-04-18 19:36:09 +0000167 GrGLSLTypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000168 this->getName().c_str(),
169 this->getArrayCount());
170 }
171 } else {
172 out->appendf("%s %s",
bsalomon@google.com018f1792013-04-18 19:36:09 +0000173 GrGLSLTypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000174 this->getName().c_str());
175 }
176 }
177
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000178 void appendArrayAccess(int index, SkString* out) const {
tomhudson@google.comda668982011-12-07 15:06:29 +0000179 out->appendf("%s[%d]%s",
180 this->getName().c_str(),
181 index,
182 fUseUniformFloatArrays ? "" : ".x");
183 }
184
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000185 void appendArrayAccess(const char* indexName, SkString* out) const {
tomhudson@google.comda668982011-12-07 15:06:29 +0000186 out->appendf("%s[%s]%s",
187 this->getName().c_str(),
188 indexName,
189 fUseUniformFloatArrays ? "" : ".x");
190 }
191
egdanielf5294392015-10-21 07:14:17 -0700192 static const char* PrecisionString(const GrGLSLCaps* glslCaps, GrSLPrecision p) {
commit-bot@chromium.org344cf452013-06-17 14:19:01 +0000193 // Desktop GLSL has added precision qualifiers but they don't do anything.
egdanielf5294392015-10-21 07:14:17 -0700194 if (glslCaps->usesPrecisionModifiers()) {
commit-bot@chromium.org344cf452013-06-17 14:19:01 +0000195 switch (p) {
bsalomonc0bd6482014-12-09 10:04:14 -0800196 case kLow_GrSLPrecision:
commit-bot@chromium.org344cf452013-06-17 14:19:01 +0000197 return "lowp ";
bsalomonc0bd6482014-12-09 10:04:14 -0800198 case kMedium_GrSLPrecision:
commit-bot@chromium.org344cf452013-06-17 14:19:01 +0000199 return "mediump ";
bsalomonc0bd6482014-12-09 10:04:14 -0800200 case kHigh_GrSLPrecision:
commit-bot@chromium.org344cf452013-06-17 14:19:01 +0000201 return "highp ";
commit-bot@chromium.org344cf452013-06-17 14:19:01 +0000202 default:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000203 SkFAIL("Unexpected precision type.");
commit-bot@chromium.org344cf452013-06-17 14:19:01 +0000204 }
205 }
206 return "";
207 }
208
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000209private:
egdanielf5294392015-10-21 07:14:17 -0700210 static const char* TypeModifierString(const GrGLSLCaps* glslCaps, TypeModifier t) {
211 GrGLSLGeneration gen = glslCaps->generation();
tomhudson@google.com086e5352011-12-08 14:44:10 +0000212 switch (t) {
213 case kNone_TypeModifier:
214 return "";
tomhudson@google.com086e5352011-12-08 14:44:10 +0000215 case kIn_TypeModifier:
bsalomon@google.com77cf4602013-04-22 21:05:48 +0000216 return "in";
217 case kInOut_TypeModifier:
218 return "inout";
219 case kOut_TypeModifier:
220 return "out";
tomhudson@google.com086e5352011-12-08 14:44:10 +0000221 case kUniform_TypeModifier:
222 return "uniform";
223 case kAttribute_TypeModifier:
bsalomon@google.come55fd0f2012-02-10 15:56:06 +0000224 return k110_GrGLSLGeneration == gen ? "attribute" : "in";
bsalomon@google.com77cf4602013-04-22 21:05:48 +0000225 case kVaryingIn_TypeModifier:
226 return k110_GrGLSLGeneration == gen ? "varying" : "in";
227 case kVaryingOut_TypeModifier:
228 return k110_GrGLSLGeneration == gen ? "varying" : "out";
tomhudson@google.com086e5352011-12-08 14:44:10 +0000229 default:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000230 SkFAIL("Unknown shader variable type modifier.");
tomhudson@google.com086e5352011-12-08 14:44:10 +0000231 return ""; // suppress warning
232 }
233 }
234
tomhudson@google.comda668982011-12-07 15:06:29 +0000235 /// Work around driver bugs on some hardware that don't correctly
236 /// support uniform float []
237 bool fUseUniformFloatArrays;
joshualitt249af152014-09-15 11:41:13 -0700238
egdanielae474182016-01-21 11:19:52 -0800239 SkString fLayoutQualifier;
240
joshualitt249af152014-09-15 11:41:13 -0700241 typedef GrShaderVar INHERITED;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000242};
243
244#endif