1 /*
2  * Copyright 2016 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 
9 #include "GrShaderVar.h"
10 #include "GrShaderCaps.h"
11 
12 static const char* type_modifier_string(GrShaderVar::TypeModifier t) {
13     switch (t) {
14         case GrShaderVar::kNone_TypeModifier: return "";
15         case GrShaderVar::kIn_TypeModifier: return "in";
16         case GrShaderVar::kInOut_TypeModifier: return "inout";
17         case GrShaderVar::kOut_TypeModifier: return "out";
18         case GrShaderVar::kUniform_TypeModifier: return "uniform";
19     }
20     SK_ABORT("Unknown shader variable type modifier.");
21     return "";
22 }
23 
24 void GrShaderVar::setIOType(GrIOType ioType) {
25     switch (ioType) {
26         case kRW_GrIOType:
27             return;
28         case kRead_GrIOType:
29             this->addModifier("readonly");
30             return;
31         case kWrite_GrIOType:
32             this->addModifier("writeonly");
33             return;
34     }
35     SK_ABORT("Unknown io type.");
36 }
37 
38 // Converts a GrSLPrecision to its corresponding GLSL precision qualifier. TODO: Remove this as we
39 // shouldn't need it with SkSL.
40 static inline const char* glsl_precision_string(GrSLPrecision p) {
41     switch (p) {
42         case kLow_GrSLPrecision:
43             return "lowp";
44         case kMedium_GrSLPrecision:
45             return "mediump";
46         case kHigh_GrSLPrecision:
47             return "highp";
48         case kDefault_GrSLPrecision:
49             return "";
50     }
51     SK_ABORT("Unexpected precision type.");
52     return "";
53 }
54 
55 void GrShaderVar::appendDecl(const GrShaderCaps* shaderCaps, SkString* out) const {
56     SkASSERT(kDefault_GrSLPrecision == fPrecision || GrSLTypeTemporarilyAcceptsPrecision(fType));
57     SkString layout = fLayoutQualifier;
58     if (!fLayoutQualifier.isEmpty()) {
59         out->appendf("layout(%s) ", fLayoutQualifier.c_str());
60     }
61     out->append(fExtraModifiers);
62     if (this->getTypeModifier() != kNone_TypeModifier) {
63         out->append(type_modifier_string(this->getTypeModifier()));
64         out->append(" ");
65     }
66     GrSLType effectiveType = this->getType();
67     if (shaderCaps->usesPrecisionModifiers() && GrSLTypeAcceptsPrecision(effectiveType)) {
68         // Desktop GLSL has added precision qualifiers but they don't do anything.
69         out->appendf("%s ", glsl_precision_string(fPrecision));
70     }
71     if (this->isArray()) {
72         if (this->isUnsizedArray()) {
73             out->appendf("%s %s[]",
74                          GrGLSLTypeString(shaderCaps, effectiveType),
75                          this->getName().c_str());
76         } else {
77             SkASSERT(this->getArrayCount() > 0);
78             out->appendf("%s %s[%d]",
79                          GrGLSLTypeString(shaderCaps, effectiveType),
80                          this->getName().c_str(),
81                          this->getArrayCount());
82         }
83     } else {
84         out->appendf("%s %s",
85                      GrGLSLTypeString(shaderCaps, effectiveType),
86                      this->getName().c_str());
87     }
88 }
89