SkSLProgram.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  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. #ifndef SKSL_PROGRAM
  8. #define SKSL_PROGRAM
  9. #include <vector>
  10. #include <memory>
  11. #include "src/sksl/ir/SkSLBoolLiteral.h"
  12. #include "src/sksl/ir/SkSLExpression.h"
  13. #include "src/sksl/ir/SkSLFloatLiteral.h"
  14. #include "src/sksl/ir/SkSLIntLiteral.h"
  15. #include "src/sksl/ir/SkSLModifiers.h"
  16. #include "src/sksl/ir/SkSLProgramElement.h"
  17. #include "src/sksl/ir/SkSLSymbolTable.h"
  18. // name of the render target width uniform
  19. #define SKSL_RTWIDTH_NAME "u_skRTWidth"
  20. // name of the render target height uniform
  21. #define SKSL_RTHEIGHT_NAME "u_skRTHeight"
  22. namespace SkSL {
  23. class Context;
  24. /**
  25. * Represents a fully-digested program, ready for code generation.
  26. */
  27. struct Program {
  28. struct Settings {
  29. struct Value {
  30. Value(bool b)
  31. : fKind(kBool_Kind)
  32. , fValue(b) {}
  33. Value(int i)
  34. : fKind(kInt_Kind)
  35. , fValue(i) {}
  36. Value(unsigned int i)
  37. : fKind(kInt_Kind)
  38. , fValue(i) {}
  39. Value(float f)
  40. : fKind(kFloat_Kind)
  41. , fValue(f) {}
  42. 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. case Program::Settings::Value::kFloat_Kind:
  53. return std::unique_ptr<Expression>(new FloatLiteral(context,
  54. offset,
  55. fValue));
  56. default:
  57. SkASSERT(false);
  58. return nullptr;
  59. }
  60. }
  61. enum {
  62. kBool_Kind,
  63. kInt_Kind,
  64. kFloat_Kind,
  65. } fKind;
  66. int fValue;
  67. };
  68. #if defined(SKSL_STANDALONE) || !SK_SUPPORT_GPU
  69. const StandaloneShaderCaps* fCaps = &standaloneCaps;
  70. #else
  71. const GrShaderCaps* fCaps = nullptr;
  72. #endif
  73. // if false, sk_FragCoord is exactly the same as gl_FragCoord. If true, the y coordinate
  74. // must be flipped.
  75. bool fFlipY = false;
  76. // If true the destination fragment color is read sk_FragColor. It must be declared inout.
  77. bool fFragColorIsInOut = false;
  78. // if true, Setting objects (e.g. sk_Caps.fbFetchSupport) should be replaced with their
  79. // constant equivalents during compilation
  80. bool fReplaceSettings = true;
  81. // if true, all halfs are forced to be floats
  82. bool fForceHighPrecision = false;
  83. // if true, add -0.5 bias to LOD of all texture lookups
  84. bool fSharpenTextures = false;
  85. std::unordered_map<String, Value> fArgs;
  86. };
  87. struct Inputs {
  88. // if true, this program requires the render target width uniform to be defined
  89. bool fRTWidth;
  90. // if true, this program requires the render target height uniform to be defined
  91. bool fRTHeight;
  92. // if true, this program must be recompiled if the flipY setting changes. If false, the
  93. // program will compile to the same code regardless of the flipY setting.
  94. bool fFlipY;
  95. void reset() {
  96. fRTWidth = false;
  97. fRTHeight = false;
  98. fFlipY = false;
  99. }
  100. bool isEmpty() {
  101. return !fRTWidth && !fRTHeight && !fFlipY;
  102. }
  103. };
  104. class iterator {
  105. public:
  106. ProgramElement& operator*() {
  107. if (fIter1 != fEnd1) {
  108. return **fIter1;
  109. }
  110. return **fIter2;
  111. }
  112. iterator& operator++() {
  113. if (fIter1 != fEnd1) {
  114. ++fIter1;
  115. return *this;
  116. }
  117. ++fIter2;
  118. return *this;
  119. }
  120. bool operator==(const iterator& other) const {
  121. return fIter1 == other.fIter1 && fIter2 == other.fIter2;
  122. }
  123. bool operator!=(const iterator& other) const {
  124. return !(*this == other);
  125. }
  126. private:
  127. using inner = std::vector<std::unique_ptr<ProgramElement>>::iterator;
  128. iterator(inner begin1, inner end1, inner begin2, inner end2)
  129. : fIter1(begin1)
  130. , fEnd1(end1)
  131. , fIter2(begin2)
  132. , fEnd2(end2) {}
  133. inner fIter1;
  134. inner fEnd1;
  135. inner fIter2;
  136. inner fEnd2;
  137. friend struct Program;
  138. };
  139. class const_iterator {
  140. public:
  141. const ProgramElement& operator*() {
  142. if (fIter1 != fEnd1) {
  143. return **fIter1;
  144. }
  145. return **fIter2;
  146. }
  147. const_iterator& operator++() {
  148. if (fIter1 != fEnd1) {
  149. ++fIter1;
  150. return *this;
  151. }
  152. ++fIter2;
  153. return *this;
  154. }
  155. bool operator==(const const_iterator& other) const {
  156. return fIter1 == other.fIter1 && fIter2 == other.fIter2;
  157. }
  158. bool operator!=(const const_iterator& other) const {
  159. return !(*this == other);
  160. }
  161. private:
  162. using inner = std::vector<std::unique_ptr<ProgramElement>>::const_iterator;
  163. const_iterator(inner begin1, inner end1, inner begin2, inner end2)
  164. : fIter1(begin1)
  165. , fEnd1(end1)
  166. , fIter2(begin2)
  167. , fEnd2(end2) {}
  168. inner fIter1;
  169. inner fEnd1;
  170. inner fIter2;
  171. inner fEnd2;
  172. friend struct Program;
  173. };
  174. enum Kind {
  175. kFragment_Kind,
  176. kVertex_Kind,
  177. kGeometry_Kind,
  178. kFragmentProcessor_Kind,
  179. kPipelineStage_Kind,
  180. kGeneric_Kind,
  181. };
  182. Program(Kind kind,
  183. std::unique_ptr<String> source,
  184. Settings settings,
  185. std::shared_ptr<Context> context,
  186. std::vector<std::unique_ptr<ProgramElement>>* inheritedElements,
  187. std::vector<std::unique_ptr<ProgramElement>> elements,
  188. std::shared_ptr<SymbolTable> symbols,
  189. Inputs inputs)
  190. : fKind(kind)
  191. , fSource(std::move(source))
  192. , fSettings(settings)
  193. , fContext(context)
  194. , fSymbols(symbols)
  195. , fInputs(inputs)
  196. , fInheritedElements(inheritedElements)
  197. , fElements(std::move(elements)) {}
  198. iterator begin() {
  199. if (fInheritedElements) {
  200. return iterator(fInheritedElements->begin(), fInheritedElements->end(),
  201. fElements.begin(), fElements.end());
  202. }
  203. return iterator(fElements.begin(), fElements.end(), fElements.end(), fElements.end());
  204. }
  205. iterator end() {
  206. if (fInheritedElements) {
  207. return iterator(fInheritedElements->end(), fInheritedElements->end(),
  208. fElements.end(), fElements.end());
  209. }
  210. return iterator(fElements.end(), fElements.end(), fElements.end(), fElements.end());
  211. }
  212. const_iterator begin() const {
  213. if (fInheritedElements) {
  214. return const_iterator(fInheritedElements->begin(), fInheritedElements->end(),
  215. fElements.begin(), fElements.end());
  216. }
  217. return const_iterator(fElements.begin(), fElements.end(), fElements.end(), fElements.end());
  218. }
  219. const_iterator end() const {
  220. if (fInheritedElements) {
  221. return const_iterator(fInheritedElements->end(), fInheritedElements->end(),
  222. fElements.end(), fElements.end());
  223. }
  224. return const_iterator(fElements.end(), fElements.end(), fElements.end(), fElements.end());
  225. }
  226. Kind fKind;
  227. std::unique_ptr<String> fSource;
  228. Settings fSettings;
  229. std::shared_ptr<Context> fContext;
  230. // it's important to keep fElements defined after (and thus destroyed before) fSymbols,
  231. // because destroying elements can modify reference counts in symbols
  232. std::shared_ptr<SymbolTable> fSymbols;
  233. Inputs fInputs;
  234. bool fIsOptimized = false;
  235. private:
  236. std::vector<std::unique_ptr<ProgramElement>>* fInheritedElements;
  237. std::vector<std::unique_ptr<ProgramElement>> fElements;
  238. friend class Compiler;
  239. };
  240. } // namespace
  241. #endif