• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 Google LLC
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 #include "include/private/SkSLModifiers.h"
9 #include "include/private/SkSLProgramElement.h"
10 #include "include/private/SkSLString.h"
11 #include "include/private/SkSLSymbol.h"
12 #include "src/sksl/SkSLAnalysis.h"
13 #include "src/sksl/SkSLModifiersPool.h"
14 #include "src/sksl/SkSLPool.h"
15 #include "src/sksl/SkSLProgramSettings.h"
16 #include "src/sksl/analysis/SkSLProgramUsage.h"
17 #include "src/sksl/ir/SkSLFunctionDeclaration.h"
18 #include "src/sksl/ir/SkSLProgram.h"
19 #include "src/sksl/ir/SkSLSymbolTable.h" // IWYU pragma: keep
20 #include "src/sksl/ir/SkSLVarDeclarations.h"
21 #include "src/sksl/ir/SkSLVariable.h"
22 
23 #include <type_traits>
24 #include <utility>
25 
26 namespace SkSL {
27 
Program(std::unique_ptr<std::string> source,std::unique_ptr<ProgramConfig> config,std::shared_ptr<Context> context,std::vector<std::unique_ptr<ProgramElement>> elements,std::vector<const ProgramElement * > sharedElements,std::unique_ptr<ModifiersPool> modifiers,std::shared_ptr<SymbolTable> symbols,std::unique_ptr<Pool> pool,Inputs inputs)28 Program::Program(std::unique_ptr<std::string> source,
29                  std::unique_ptr<ProgramConfig> config,
30                  std::shared_ptr<Context> context,
31                  std::vector<std::unique_ptr<ProgramElement>> elements,
32                  std::vector<const ProgramElement*> sharedElements,
33                  std::unique_ptr<ModifiersPool> modifiers,
34                  std::shared_ptr<SymbolTable> symbols,
35                  std::unique_ptr<Pool> pool,
36                  Inputs inputs)
37         : fSource(std::move(source))
38         , fConfig(std::move(config))
39         , fContext(context)
40         , fModifiers(std::move(modifiers))
41         , fSymbols(symbols)
42         , fPool(std::move(pool))
43         , fOwnedElements(std::move(elements))
44         , fSharedElements(std::move(sharedElements))
45         , fInputs(inputs) {
46     fUsage = Analysis::GetUsage(*this);
47 }
48 
~Program()49 Program::~Program() {
50     // Some or all of the program elements are in the pool. To free them safely, we must attach
51     // the pool before destroying any program elements. (Otherwise, we may accidentally call
52     // delete on a pooled node.)
53     AutoAttachPoolToThread attach(fPool.get());
54 
55     fOwnedElements.clear();
56     fContext.reset();
57     fSymbols.reset();
58     fModifiers.reset();
59 }
60 
description() const61 std::string Program::description() const {
62     std::string result = fConfig->versionDescription();
63     for (const ProgramElement* e : this->elements()) {
64         result += e->description();
65     }
66     return result;
67 }
68 
getFunction(const char * functionName) const69 const FunctionDeclaration* Program::getFunction(const char* functionName) const {
70     const Symbol* symbol = fSymbols->find(functionName);
71     bool valid = symbol && symbol->is<FunctionDeclaration>() &&
72                  symbol->as<FunctionDeclaration>().definition();
73     return valid ? &symbol->as<FunctionDeclaration>() : nullptr;
74 }
75 
gather_uniforms(UniformInfo * info,const Type & type,const std::string & name)76 static void gather_uniforms(UniformInfo* info, const Type& type, const std::string& name) {
77     switch (type.typeKind()) {
78         case Type::TypeKind::kStruct:
79             for (const auto& f : type.fields()) {
80                 gather_uniforms(info, *f.fType, name + "." + std::string(f.fName));
81             }
82             break;
83         case Type::TypeKind::kArray:
84             for (int i = 0; i < type.columns(); ++i) {
85                 gather_uniforms(info, type.componentType(),
86                                 String::printf("%s[%d]", name.c_str(), i));
87             }
88             break;
89         case Type::TypeKind::kScalar:
90         case Type::TypeKind::kVector:
91         case Type::TypeKind::kMatrix:
92             info->fUniforms.push_back({name, type.componentType().numberKind(),
93                                        type.rows(), type.columns(), info->fUniformSlotCount});
94             info->fUniformSlotCount += type.slotCount();
95             break;
96         default:
97             break;
98     }
99 }
100 
getUniformInfo()101 std::unique_ptr<UniformInfo> Program::getUniformInfo() {
102     auto info = std::make_unique<UniformInfo>();
103     for (const ProgramElement* e : this->elements()) {
104         if (!e->is<GlobalVarDeclaration>()) {
105             continue;
106         }
107         const GlobalVarDeclaration& decl = e->as<GlobalVarDeclaration>();
108         const Variable& var = *decl.varDeclaration().var();
109         if (var.modifiers().fFlags & Modifiers::kUniform_Flag) {
110             gather_uniforms(info.get(), var.type(), std::string(var.name()));
111         }
112     }
113     return info;
114 }
115 
116 }  // namespace SkSL
117