xref: /aosp_15_r20/external/skia/src/sksl/ir/SkSLInterfaceBlock.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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