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 #ifndef SKSL_INTERFACEBLOCK 9 #define SKSL_INTERFACEBLOCK 10 11 #include "src/sksl/ir/SkSLProgramElement.h" 12 #include "src/sksl/ir/SkSLSymbolTable.h" 13 #include "src/sksl/ir/SkSLVarDeclarations.h" 14 15 namespace SkSL { 16 17 /** 18 * An interface block, as in: 19 * 20 * out sk_PerVertex { 21 * layout(builtin=0) float4 sk_Position; 22 * layout(builtin=1) float sk_PointSize; 23 * }; 24 * 25 * At the IR level, this is represented by a single variable of struct type. 26 */ 27 class InterfaceBlock final : public ProgramElement { 28 public: 29 static constexpr Kind kProgramElementKind = Kind::kInterfaceBlock; 30 InterfaceBlock(int offset,const Variable * var,String typeName,String instanceName,ExpressionArray sizes,std::shared_ptr<SymbolTable> typeOwner)31 InterfaceBlock(int offset, const Variable* var, String typeName, String instanceName, 32 ExpressionArray sizes, std::shared_ptr<SymbolTable> typeOwner) 33 : INHERITED(offset, kProgramElementKind) 34 , fVariable(var) 35 , fTypeName(std::move(typeName)) 36 , fInstanceName(std::move(instanceName)) 37 , fSizes(std::move(sizes)) 38 , fTypeOwner(std::move(typeOwner)) {} 39 variable()40 const Variable& variable() const { 41 return *fVariable; 42 } 43 setVariable(const Variable * var)44 void setVariable(const Variable* var) { 45 fVariable = var; 46 } 47 typeName()48 const String& typeName() const { 49 return fTypeName; 50 } 51 instanceName()52 const String& instanceName() const { 53 return fInstanceName; 54 } 55 typeOwner()56 const std::shared_ptr<SymbolTable>& typeOwner() const { 57 return fTypeOwner; 58 } 59 sizes()60 ExpressionArray& sizes() { 61 return fSizes; 62 } 63 sizes()64 const ExpressionArray& sizes() const { 65 return fSizes; 66 } 67 clone()68 std::unique_ptr<ProgramElement> clone() const override { 69 ExpressionArray sizesClone; 70 sizesClone.reserve_back(this->sizes().size()); 71 for (const auto& size : this->sizes()) { 72 sizesClone.push_back(size ? size->clone() : nullptr); 73 } 74 return std::make_unique<InterfaceBlock>(fOffset, &this->variable(), this->typeName(), 75 this->instanceName(), std::move(sizesClone), 76 SymbolTable::WrapIfBuiltin(this->typeOwner())); 77 } 78 description()79 String description() const override { 80 String result = this->variable().modifiers().description() + this->typeName() + " {\n"; 81 const Type* structType = &this->variable().type(); 82 while (structType->typeKind() == Type::TypeKind::kArray) { 83 structType = &structType->componentType(); 84 } 85 for (const auto& f : structType->fields()) { 86 result += f.description() + "\n"; 87 } 88 result += "}"; 89 if (this->instanceName().size()) { 90 result += " " + this->instanceName(); 91 for (const auto& size : this->sizes()) { 92 result += "["; 93 if (size) { 94 result += size->description(); 95 } 96 result += "]"; 97 } 98 } 99 return result + ";"; 100 } 101 102 private: 103 const Variable* fVariable; 104 String fTypeName; 105 String fInstanceName; 106 ExpressionArray fSizes; 107 std::shared_ptr<SymbolTable> fTypeOwner; 108 109 using INHERITED = ProgramElement; 110 }; 111 112 } // namespace SkSL 113 114 #endif 115