1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2016 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #ifndef SKSL_PROGRAM 9*c8dee2aaSAndroid Build Coastguard Worker #define SKSL_PROGRAM 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/ir/SkSLType.h" 12*c8dee2aaSAndroid Build Coastguard Worker 13*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint> 14*c8dee2aaSAndroid Build Coastguard Worker #include <memory> 15*c8dee2aaSAndroid Build Coastguard Worker #include <string> 16*c8dee2aaSAndroid Build Coastguard Worker #include <vector> 17*c8dee2aaSAndroid Build Coastguard Worker 18*c8dee2aaSAndroid Build Coastguard Worker // name of the uniform used to handle features that are sensitive to whether Y is flipped. 19*c8dee2aaSAndroid Build Coastguard Worker #define SKSL_RTFLIP_NAME "u_skRTFlip" 20*c8dee2aaSAndroid Build Coastguard Worker 21*c8dee2aaSAndroid Build Coastguard Worker namespace SkSL { 22*c8dee2aaSAndroid Build Coastguard Worker 23*c8dee2aaSAndroid Build Coastguard Worker class Context; 24*c8dee2aaSAndroid Build Coastguard Worker class FunctionDeclaration; 25*c8dee2aaSAndroid Build Coastguard Worker class Pool; 26*c8dee2aaSAndroid Build Coastguard Worker class ProgramElement; 27*c8dee2aaSAndroid Build Coastguard Worker class ProgramUsage; 28*c8dee2aaSAndroid Build Coastguard Worker class SymbolTable; 29*c8dee2aaSAndroid Build Coastguard Worker struct ProgramConfig; 30*c8dee2aaSAndroid Build Coastguard Worker 31*c8dee2aaSAndroid Build Coastguard Worker /** Represents a list the Uniforms contained within a Program. */ 32*c8dee2aaSAndroid Build Coastguard Worker struct UniformInfo { 33*c8dee2aaSAndroid Build Coastguard Worker struct Uniform { 34*c8dee2aaSAndroid Build Coastguard Worker std::string fName; 35*c8dee2aaSAndroid Build Coastguard Worker SkSL::Type::NumberKind fKind; 36*c8dee2aaSAndroid Build Coastguard Worker int fColumns; 37*c8dee2aaSAndroid Build Coastguard Worker int fRows; 38*c8dee2aaSAndroid Build Coastguard Worker int fSlot; 39*c8dee2aaSAndroid Build Coastguard Worker }; 40*c8dee2aaSAndroid Build Coastguard Worker std::vector<Uniform> fUniforms; 41*c8dee2aaSAndroid Build Coastguard Worker int fUniformSlotCount = 0; 42*c8dee2aaSAndroid Build Coastguard Worker }; 43*c8dee2aaSAndroid Build Coastguard Worker 44*c8dee2aaSAndroid Build Coastguard Worker /** A program's inputs and outputs. */ 45*c8dee2aaSAndroid Build Coastguard Worker struct ProgramInterface { 46*c8dee2aaSAndroid Build Coastguard Worker enum RTFlip : uint8_t { 47*c8dee2aaSAndroid Build Coastguard Worker kRTFlip_None = 0b0000'0000, 48*c8dee2aaSAndroid Build Coastguard Worker kRTFlip_FragCoord = 0b0000'0001, 49*c8dee2aaSAndroid Build Coastguard Worker kRTFlip_Clockwise = 0b0000'0010, 50*c8dee2aaSAndroid Build Coastguard Worker kRTFlip_Derivative = 0b0000'0100, 51*c8dee2aaSAndroid Build Coastguard Worker }; 52*c8dee2aaSAndroid Build Coastguard Worker uint8_t fRTFlipUniform = kRTFlip_None; 53*c8dee2aaSAndroid Build Coastguard Worker bool fUseLastFragColor = false; 54*c8dee2aaSAndroid Build Coastguard Worker bool fOutputSecondaryColor = false; 55*c8dee2aaSAndroid Build Coastguard Worker 56*c8dee2aaSAndroid Build Coastguard Worker bool operator==(const ProgramInterface& that) const { 57*c8dee2aaSAndroid Build Coastguard Worker return fRTFlipUniform == that.fRTFlipUniform && 58*c8dee2aaSAndroid Build Coastguard Worker fUseLastFragColor == that.fUseLastFragColor && 59*c8dee2aaSAndroid Build Coastguard Worker fOutputSecondaryColor == that.fOutputSecondaryColor; 60*c8dee2aaSAndroid Build Coastguard Worker } 61*c8dee2aaSAndroid Build Coastguard Worker bool operator!=(const ProgramInterface& that) const { return !(*this == that); } 62*c8dee2aaSAndroid Build Coastguard Worker }; 63*c8dee2aaSAndroid Build Coastguard Worker 64*c8dee2aaSAndroid Build Coastguard Worker /** Represents a fully-digested program, ready for code generation. */ 65*c8dee2aaSAndroid Build Coastguard Worker struct Program { 66*c8dee2aaSAndroid Build Coastguard Worker Program(std::unique_ptr<std::string> source, 67*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<ProgramConfig> config, 68*c8dee2aaSAndroid Build Coastguard Worker std::shared_ptr<Context> context, 69*c8dee2aaSAndroid Build Coastguard Worker std::vector<std::unique_ptr<ProgramElement>> elements, 70*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SymbolTable> symbols, 71*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Pool> pool); 72*c8dee2aaSAndroid Build Coastguard Worker 73*c8dee2aaSAndroid Build Coastguard Worker ~Program(); 74*c8dee2aaSAndroid Build Coastguard Worker 75*c8dee2aaSAndroid Build Coastguard Worker class ElementsCollection { 76*c8dee2aaSAndroid Build Coastguard Worker public: 77*c8dee2aaSAndroid Build Coastguard Worker class iterator { 78*c8dee2aaSAndroid Build Coastguard Worker public: 79*c8dee2aaSAndroid Build Coastguard Worker const ProgramElement* operator*() { 80*c8dee2aaSAndroid Build Coastguard Worker if (fShared != fSharedEnd) { 81*c8dee2aaSAndroid Build Coastguard Worker return *fShared; 82*c8dee2aaSAndroid Build Coastguard Worker } else { 83*c8dee2aaSAndroid Build Coastguard Worker return fOwned->get(); 84*c8dee2aaSAndroid Build Coastguard Worker } 85*c8dee2aaSAndroid Build Coastguard Worker } 86*c8dee2aaSAndroid Build Coastguard Worker 87*c8dee2aaSAndroid Build Coastguard Worker iterator& operator++() { 88*c8dee2aaSAndroid Build Coastguard Worker if (fShared != fSharedEnd) { 89*c8dee2aaSAndroid Build Coastguard Worker ++fShared; 90*c8dee2aaSAndroid Build Coastguard Worker } else { 91*c8dee2aaSAndroid Build Coastguard Worker ++fOwned; 92*c8dee2aaSAndroid Build Coastguard Worker } 93*c8dee2aaSAndroid Build Coastguard Worker return *this; 94*c8dee2aaSAndroid Build Coastguard Worker } 95*c8dee2aaSAndroid Build Coastguard Worker 96*c8dee2aaSAndroid Build Coastguard Worker bool operator==(const iterator& other) const { 97*c8dee2aaSAndroid Build Coastguard Worker return fOwned == other.fOwned && fShared == other.fShared; 98*c8dee2aaSAndroid Build Coastguard Worker } 99*c8dee2aaSAndroid Build Coastguard Worker 100*c8dee2aaSAndroid Build Coastguard Worker bool operator!=(const iterator& other) const { 101*c8dee2aaSAndroid Build Coastguard Worker return !(*this == other); 102*c8dee2aaSAndroid Build Coastguard Worker } 103*c8dee2aaSAndroid Build Coastguard Worker 104*c8dee2aaSAndroid Build Coastguard Worker private: 105*c8dee2aaSAndroid Build Coastguard Worker using Owned = std::vector<std::unique_ptr<ProgramElement>>::const_iterator; 106*c8dee2aaSAndroid Build Coastguard Worker using Shared = std::vector<const ProgramElement*>::const_iterator; 107*c8dee2aaSAndroid Build Coastguard Worker friend class ElementsCollection; 108*c8dee2aaSAndroid Build Coastguard Worker iteratorProgram109*c8dee2aaSAndroid Build Coastguard Worker iterator(Owned owned, Owned ownedEnd, Shared shared, Shared sharedEnd) 110*c8dee2aaSAndroid Build Coastguard Worker : fOwned(owned), fOwnedEnd(ownedEnd), fShared(shared), fSharedEnd(sharedEnd) {} 111*c8dee2aaSAndroid Build Coastguard Worker 112*c8dee2aaSAndroid Build Coastguard Worker Owned fOwned; 113*c8dee2aaSAndroid Build Coastguard Worker Owned fOwnedEnd; 114*c8dee2aaSAndroid Build Coastguard Worker Shared fShared; 115*c8dee2aaSAndroid Build Coastguard Worker Shared fSharedEnd; 116*c8dee2aaSAndroid Build Coastguard Worker }; 117*c8dee2aaSAndroid Build Coastguard Worker beginProgram118*c8dee2aaSAndroid Build Coastguard Worker iterator begin() const { 119*c8dee2aaSAndroid Build Coastguard Worker return iterator(fProgram.fOwnedElements.begin(), fProgram.fOwnedElements.end(), 120*c8dee2aaSAndroid Build Coastguard Worker fProgram.fSharedElements.begin(), fProgram.fSharedElements.end()); 121*c8dee2aaSAndroid Build Coastguard Worker } 122*c8dee2aaSAndroid Build Coastguard Worker endProgram123*c8dee2aaSAndroid Build Coastguard Worker iterator end() const { 124*c8dee2aaSAndroid Build Coastguard Worker return iterator(fProgram.fOwnedElements.end(), fProgram.fOwnedElements.end(), 125*c8dee2aaSAndroid Build Coastguard Worker fProgram.fSharedElements.end(), fProgram.fSharedElements.end()); 126*c8dee2aaSAndroid Build Coastguard Worker } 127*c8dee2aaSAndroid Build Coastguard Worker 128*c8dee2aaSAndroid Build Coastguard Worker private: 129*c8dee2aaSAndroid Build Coastguard Worker friend struct Program; 130*c8dee2aaSAndroid Build Coastguard Worker ElementsCollectionProgram131*c8dee2aaSAndroid Build Coastguard Worker ElementsCollection(const Program& program) : fProgram(program) {} 132*c8dee2aaSAndroid Build Coastguard Worker const Program& fProgram; 133*c8dee2aaSAndroid Build Coastguard Worker }; 134*c8dee2aaSAndroid Build Coastguard Worker 135*c8dee2aaSAndroid Build Coastguard Worker /** 136*c8dee2aaSAndroid Build Coastguard Worker * Iterates over *all* elements in this Program, both owned and shared (builtin). The iterator's 137*c8dee2aaSAndroid Build Coastguard Worker * value type is `const ProgramElement*`, so it's clear that you *must not* modify anything (as 138*c8dee2aaSAndroid Build Coastguard Worker * you might be mutating shared data). 139*c8dee2aaSAndroid Build Coastguard Worker */ elementsProgram140*c8dee2aaSAndroid Build Coastguard Worker ElementsCollection elements() const { return ElementsCollection(*this); } 141*c8dee2aaSAndroid Build Coastguard Worker 142*c8dee2aaSAndroid Build Coastguard Worker /** 143*c8dee2aaSAndroid Build Coastguard Worker * Returns a function declaration with the given name; null is returned if the function doesn't 144*c8dee2aaSAndroid Build Coastguard Worker * exist or has no definition. If the function might have overloads, you can use nextOverload() 145*c8dee2aaSAndroid Build Coastguard Worker * to search for the function with the expected parameter list. 146*c8dee2aaSAndroid Build Coastguard Worker */ 147*c8dee2aaSAndroid Build Coastguard Worker const FunctionDeclaration* getFunction(const char* functionName) const; 148*c8dee2aaSAndroid Build Coastguard Worker 149*c8dee2aaSAndroid Build Coastguard Worker std::string description() const; usageProgram150*c8dee2aaSAndroid Build Coastguard Worker const ProgramUsage* usage() const { return fUsage.get(); } 151*c8dee2aaSAndroid Build Coastguard Worker 152*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<std::string> fSource; 153*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<ProgramConfig> fConfig; 154*c8dee2aaSAndroid Build Coastguard Worker std::shared_ptr<Context> fContext; 155*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<ProgramUsage> fUsage; 156*c8dee2aaSAndroid Build Coastguard Worker // it's important to keep fOwnedElements defined after (and thus destroyed before) fSymbols, 157*c8dee2aaSAndroid Build Coastguard Worker // because an IR element might access the symbol table during its destruction 158*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SymbolTable> fSymbols; 159*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Pool> fPool; 160*c8dee2aaSAndroid Build Coastguard Worker // Contains *only* elements owned exclusively by this program. 161*c8dee2aaSAndroid Build Coastguard Worker std::vector<std::unique_ptr<ProgramElement>> fOwnedElements; 162*c8dee2aaSAndroid Build Coastguard Worker // Contains *only* elements owned by a built-in module that are included in this program. 163*c8dee2aaSAndroid Build Coastguard Worker // Use elements() to iterate over the combined set of owned + shared elements. 164*c8dee2aaSAndroid Build Coastguard Worker std::vector<const ProgramElement*> fSharedElements; 165*c8dee2aaSAndroid Build Coastguard Worker ProgramInterface fInterface; 166*c8dee2aaSAndroid Build Coastguard Worker 167*c8dee2aaSAndroid Build Coastguard Worker using Interface = ProgramInterface; 168*c8dee2aaSAndroid Build Coastguard Worker }; 169*c8dee2aaSAndroid Build Coastguard Worker 170*c8dee2aaSAndroid Build Coastguard Worker } // namespace SkSL 171*c8dee2aaSAndroid Build Coastguard Worker 172*c8dee2aaSAndroid Build Coastguard Worker #endif 173