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