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