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 <vector> 12 #include <memory> 13 14 #include "SkSLBoolLiteral.h" 15 #include "SkSLExpression.h" 16 #include "SkSLIntLiteral.h" 17 #include "SkSLModifiers.h" 18 #include "SkSLProgramElement.h" 19 #include "SkSLSymbolTable.h" 20 21 // name of the render target height uniform 22 #define SKSL_RTHEIGHT_NAME "u_skRTHeight" 23 24 namespace SkSL { 25 26 class Context; 27 28 /** 29 * Represents a fully-digested program, ready for code generation. 30 */ 31 struct Program { 32 struct Settings { 33 struct Value { ValueProgram::Settings::Value34 Value(bool b) 35 : fKind(kBool_Kind) 36 , fValue(b) {} 37 ValueProgram::Settings::Value38 Value(int i) 39 : fKind(kInt_Kind) 40 , fValue(i) {} 41 literalProgram::Settings::Value42 std::unique_ptr<Expression> literal(const Context& context, int offset) const { 43 switch (fKind) { 44 case Program::Settings::Value::kBool_Kind: 45 return std::unique_ptr<Expression>(new BoolLiteral(context, 46 offset, 47 fValue)); 48 case Program::Settings::Value::kInt_Kind: 49 return std::unique_ptr<Expression>(new IntLiteral(context, 50 offset, 51 fValue)); 52 default: 53 ASSERT(false); 54 return nullptr; 55 } 56 } 57 58 enum { 59 kBool_Kind, 60 kInt_Kind, 61 } fKind; 62 63 int fValue; 64 }; 65 66 #ifdef SKSL_STANDALONE 67 const StandaloneShaderCaps* fCaps = &standaloneCaps; 68 #else 69 const GrShaderCaps* fCaps = nullptr; 70 #endif 71 // if false, sk_FragCoord is exactly the same as gl_FragCoord. If true, the y coordinate 72 // must be flipped. 73 bool fFlipY = false; 74 // If true the destination fragment color is read sk_FragColor. It must be declared inout. 75 bool fFragColorIsInOut = false; 76 // if true, Setting objects (e.g. sk_Caps.fbFetchSupport) should be replaced with their 77 // constant equivalents during compilation 78 bool fReplaceSettings = true; 79 // if true, all halfs are forced to be floats 80 bool fForceHighPrecision = false; 81 // if true, add -0.5 bias to LOD of all texture lookups 82 bool fSharpenTextures = false; 83 std::unordered_map<String, Value> fArgs; 84 }; 85 86 struct Inputs { 87 // if true, this program requires the render target height uniform to be defined 88 bool fRTHeight; 89 90 // if true, this program must be recompiled if the flipY setting changes. If false, the 91 // program will compile to the same code regardless of the flipY setting. 92 bool fFlipY; 93 resetProgram::Inputs94 void reset() { 95 fRTHeight = false; 96 fFlipY = false; 97 } 98 isEmptyProgram::Inputs99 bool isEmpty() { 100 return !fRTHeight && !fFlipY; 101 } 102 }; 103 104 enum Kind { 105 kFragment_Kind, 106 kVertex_Kind, 107 kGeometry_Kind, 108 kFragmentProcessor_Kind 109 }; 110 ProgramProgram111 Program(Kind kind, 112 std::unique_ptr<String> source, 113 Settings settings, 114 Context* context, 115 std::vector<std::unique_ptr<ProgramElement>> elements, 116 std::shared_ptr<SymbolTable> symbols, 117 Inputs inputs) 118 : fKind(kind) 119 , fSource(std::move(source)) 120 , fSettings(settings) 121 , fContext(context) 122 , fSymbols(symbols) 123 , fElements(std::move(elements)) 124 , fInputs(inputs) {} 125 126 Kind fKind; 127 std::unique_ptr<String> fSource; 128 Settings fSettings; 129 Context* fContext; 130 // it's important to keep fElements defined after (and thus destroyed before) fSymbols, 131 // because destroying elements can modify reference counts in symbols 132 std::shared_ptr<SymbolTable> fSymbols; 133 std::vector<std::unique_ptr<ProgramElement>> fElements; 134 Inputs fInputs; 135 }; 136 137 } // namespace 138 139 #endif 140