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_PROGRAM 9 #define SKSL_PROGRAM 10 11 #include "src/sksl/ir/SkSLType.h" 12 13 #include <memory> 14 #include <string> 15 #include <vector> 16 17 // name of the uniform used to handle features that are sensitive to whether Y is flipped. 18 // TODO: find a better home for this constant 19 #define SKSL_RTFLIP_NAME "u_skRTFlip" 20 21 namespace SkSL { 22 23 class Context; 24 class FunctionDeclaration; 25 class ModifiersPool; 26 class Pool; 27 class ProgramElement; 28 class ProgramUsage; 29 class SymbolTable; 30 struct ProgramConfig; 31 32 /** Represents a list the Uniforms contained within a Program. */ 33 struct UniformInfo { 34 struct Uniform { 35 std::string fName; 36 SkSL::Type::NumberKind fKind; 37 int fColumns; 38 int fRows; 39 int fSlot; 40 }; 41 std::vector<Uniform> fUniforms; 42 int fUniformSlotCount = 0; 43 }; 44 45 /** 46 * Represents a fully-digested program, ready for code generation. 47 */ 48 struct Program { 49 struct Inputs { 50 bool fUseFlipRTUniform = false; 51 bool operator==(const Inputs& that) const { 52 return fUseFlipRTUniform == that.fUseFlipRTUniform; 53 } 54 bool operator!=(const Inputs& that) const { return !(*this == that); } 55 }; 56 57 Program(std::unique_ptr<std::string> source, 58 std::unique_ptr<ProgramConfig> config, 59 std::shared_ptr<Context> context, 60 std::vector<std::unique_ptr<ProgramElement>> elements, 61 std::vector<const ProgramElement*> sharedElements, 62 std::unique_ptr<ModifiersPool> modifiers, 63 std::shared_ptr<SymbolTable> symbols, 64 std::unique_ptr<Pool> pool, 65 Inputs inputs); 66 67 ~Program(); 68 69 class ElementsCollection { 70 public: 71 class iterator { 72 public: 73 const ProgramElement* operator*() { 74 if (fShared != fSharedEnd) { 75 return *fShared; 76 } else { 77 return fOwned->get(); 78 } 79 } 80 81 iterator& operator++() { 82 if (fShared != fSharedEnd) { 83 ++fShared; 84 } else { 85 ++fOwned; 86 } 87 return *this; 88 } 89 90 bool operator==(const iterator& other) const { 91 return fOwned == other.fOwned && fShared == other.fShared; 92 } 93 94 bool operator!=(const iterator& other) const { 95 return !(*this == other); 96 } 97 98 private: 99 using Owned = std::vector<std::unique_ptr<ProgramElement>>::const_iterator; 100 using Shared = std::vector<const ProgramElement*>::const_iterator; 101 friend class ElementsCollection; 102 iteratorProgram103 iterator(Owned owned, Owned ownedEnd, Shared shared, Shared sharedEnd) 104 : fOwned(owned), fOwnedEnd(ownedEnd), fShared(shared), fSharedEnd(sharedEnd) {} 105 106 Owned fOwned; 107 Owned fOwnedEnd; 108 Shared fShared; 109 Shared fSharedEnd; 110 }; 111 beginProgram112 iterator begin() const { 113 return iterator(fProgram.fOwnedElements.begin(), fProgram.fOwnedElements.end(), 114 fProgram.fSharedElements.begin(), fProgram.fSharedElements.end()); 115 } 116 endProgram117 iterator end() const { 118 return iterator(fProgram.fOwnedElements.end(), fProgram.fOwnedElements.end(), 119 fProgram.fSharedElements.end(), fProgram.fSharedElements.end()); 120 } 121 122 private: 123 friend struct Program; 124 ElementsCollectionProgram125 ElementsCollection(const Program& program) : fProgram(program) {} 126 const Program& fProgram; 127 }; 128 129 /** 130 * Iterates over *all* elements in this Program, both owned and shared (builtin). The iterator's 131 * value type is `const ProgramElement*`, so it's clear that you *must not* modify anything (as 132 * you might be mutating shared data). 133 */ elementsProgram134 ElementsCollection elements() const { return ElementsCollection(*this); } 135 136 /** 137 * Returns a function declaration with the given name; null is returned if the function doesn't 138 * exist or has no definition. If the function might have overloads, you can use nextOverload() 139 * to search for the function with the expected parameter list. 140 */ 141 const FunctionDeclaration* getFunction(const char* functionName) const; 142 143 /** 144 * Returns a list of uniforms used by this Program. The uniform list will exclude opaque types 145 * like textures, samplers, or child effects. 146 */ 147 std::unique_ptr<UniformInfo> getUniformInfo(); 148 149 std::string description() const; usageProgram150 const ProgramUsage* usage() const { return fUsage.get(); } 151 152 std::unique_ptr<std::string> fSource; 153 std::unique_ptr<ProgramConfig> fConfig; 154 std::shared_ptr<Context> fContext; 155 std::unique_ptr<ProgramUsage> fUsage; 156 std::unique_ptr<ModifiersPool> fModifiers; 157 // it's important to keep fOwnedElements defined after (and thus destroyed before) fSymbols, 158 // because destroying elements can modify reference counts in symbols 159 std::shared_ptr<SymbolTable> fSymbols; 160 std::unique_ptr<Pool> fPool; 161 // Contains *only* elements owned exclusively by this program. 162 std::vector<std::unique_ptr<ProgramElement>> fOwnedElements; 163 // Contains *only* elements owned by a built-in module that are included in this program. 164 // Use elements() to iterate over the combined set of owned + shared elements. 165 std::vector<const ProgramElement*> fSharedElements; 166 Inputs fInputs; 167 }; 168 169 } // namespace SkSL 170 171 #endif 172