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 "include/core/SkTypes.h" 12 #include "include/private/base/SkTArray.h" 13 #include "src/sksl/SkSLPosition.h" 14 #include "src/sksl/ir/SkSLIRNode.h" 15 #include "src/sksl/ir/SkSLProgramElement.h" 16 #include "src/sksl/ir/SkSLType.h" 17 #include "src/sksl/ir/SkSLVariable.h" 18 19 #include <memory> 20 #include <string> 21 #include <string_view> 22 23 namespace SkSL { 24 25 class Context; 26 struct Modifiers; 27 28 /** 29 * An interface block, as in: 30 * 31 * out sk_PerVertex { 32 * layout(builtin=0) float4 sk_Position; 33 * layout(builtin=1) float sk_PointSize; 34 * }; 35 * 36 * At the IR level, this is represented by a single variable of struct type. 37 */ 38 class InterfaceBlock final : public ProgramElement { 39 public: 40 inline static constexpr Kind kIRNodeKind = Kind::kInterfaceBlock; 41 InterfaceBlock(Position pos,Variable * var)42 InterfaceBlock(Position pos, Variable* var) 43 : INHERITED(pos, kIRNodeKind) 44 , fVariable(var) { 45 SkASSERT(fVariable->type().componentType().isInterfaceBlock()); 46 fVariable->setInterfaceBlock(this); 47 } 48 49 ~InterfaceBlock() override; 50 51 // Returns an InterfaceBlock; errors are reported to the ErrorReporter. 52 // The caller is responsible for adding the InterfaceBlock to the program elements. 53 // The program's RTAdjustData will be updated if the InterfaceBlock contains sk_RTAdjust. 54 // The passed-in symbol table will be updated with a reference to the interface block variable 55 // (if it is named) or each of the interface block fields (if it is anonymous). 56 static std::unique_ptr<InterfaceBlock> Convert(const Context& context, 57 Position pos, 58 const Modifiers& modifiers, 59 std::string_view typeName, 60 skia_private::TArray<Field> fields, 61 std::string_view varName, 62 int arraySize); 63 64 // Returns an InterfaceBlock; errors are reported via SkASSERT. 65 // The caller is responsible for adding the InterfaceBlock to the program elements. 66 // The passed-in symbol table will be updated with a reference to the interface block variable 67 // (if it is named) or each of the interface block fields (if it is anonymous). 68 static std::unique_ptr<InterfaceBlock> Make(const Context& context, 69 Position pos, 70 Variable* variable); 71 var()72 Variable* var() const { 73 return fVariable; 74 } 75 detachDeadVariable()76 void detachDeadVariable() { 77 fVariable = nullptr; 78 } 79 typeName()80 std::string_view typeName() const { 81 return fVariable->type().componentType().name(); 82 } 83 instanceName()84 std::string_view instanceName() const { 85 return fVariable->name(); 86 } 87 arraySize()88 int arraySize() const { 89 return fVariable->type().isArray() ? fVariable->type().columns() : 0; 90 } 91 92 std::string description() const override; 93 94 private: 95 Variable* fVariable; 96 97 using INHERITED = ProgramElement; 98 }; 99 100 } // namespace SkSL 101 102 #endif 103