• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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