SkSLPipelineStageCodeGenerator.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. /*
  2. * Copyright 2018 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. #include "src/sksl/SkSLPipelineStageCodeGenerator.h"
  8. #include "src/sksl/SkSLCompiler.h"
  9. #include "src/sksl/SkSLHCodeGenerator.h"
  10. namespace SkSL {
  11. PipelineStageCodeGenerator::PipelineStageCodeGenerator(
  12. const Context* context,
  13. const Program* program,
  14. ErrorReporter* errors,
  15. OutputStream* out,
  16. std::vector<Compiler::FormatArg>* outFormatArgs)
  17. : INHERITED(context, program, errors, out)
  18. , fName("Temp")
  19. , fFullName(String::printf("Gr%s", fName.c_str()))
  20. , fSectionAndParameterHelper(*program, *errors)
  21. , fFormatArgs(outFormatArgs) {}
  22. void PipelineStageCodeGenerator::writef(const char* s, va_list va) {
  23. static constexpr int BUFFER_SIZE = 1024;
  24. va_list copy;
  25. va_copy(copy, va);
  26. char buffer[BUFFER_SIZE];
  27. int length = vsnprintf(buffer, BUFFER_SIZE, s, va);
  28. if (length < BUFFER_SIZE) {
  29. fOut->write(buffer, length);
  30. } else {
  31. std::unique_ptr<char[]> heap(new char[length + 1]);
  32. vsprintf(heap.get(), s, copy);
  33. fOut->write(heap.get(), length);
  34. }
  35. va_end(copy);
  36. }
  37. void PipelineStageCodeGenerator::writef(const char* s, ...) {
  38. va_list va;
  39. va_start(va, s);
  40. this->writef(s, va);
  41. va_end(va);
  42. }
  43. void PipelineStageCodeGenerator::writeHeader() {
  44. }
  45. bool PipelineStageCodeGenerator::usesPrecisionModifiers() const {
  46. return false;
  47. }
  48. String PipelineStageCodeGenerator::getTypeName(const Type& type) {
  49. return type.name();
  50. }
  51. void PipelineStageCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
  52. Precedence parentPrecedence) {
  53. if (b.fOperator == Token::PERCENT) {
  54. // need to use "%%" instead of "%" b/c the code will be inside of a printf
  55. Precedence precedence = GetBinaryPrecedence(b.fOperator);
  56. if (precedence >= parentPrecedence) {
  57. this->write("(");
  58. }
  59. this->writeExpression(*b.fLeft, precedence);
  60. this->write(" %% ");
  61. this->writeExpression(*b.fRight, precedence);
  62. if (precedence >= parentPrecedence) {
  63. this->write(")");
  64. }
  65. } else {
  66. INHERITED::writeBinaryExpression(b, parentPrecedence);
  67. }
  68. }
  69. void PipelineStageCodeGenerator::writeFunctionCall(const FunctionCall& c) {
  70. if (c.fFunction.fBuiltin && c.fFunction.fName == "process") {
  71. SkASSERT(c.fArguments.size() == 1);
  72. SkASSERT(Expression::kVariableReference_Kind == c.fArguments[0]->fKind);
  73. int index = 0;
  74. bool found = false;
  75. for (const auto& p : fProgram) {
  76. if (ProgramElement::kVar_Kind == p.fKind) {
  77. const VarDeclarations& decls = (const VarDeclarations&) p;
  78. for (const auto& raw : decls.fVars) {
  79. VarDeclaration& decl = (VarDeclaration&) *raw;
  80. if (decl.fVar == &((VariableReference&) *c.fArguments[0]).fVariable) {
  81. found = true;
  82. } else if (decl.fVar->fType == *fContext.fFragmentProcessor_Type) {
  83. ++index;
  84. }
  85. }
  86. }
  87. if (found) {
  88. break;
  89. }
  90. }
  91. SkASSERT(found);
  92. fExtraEmitCodeCode += " this->emitChild(" + to_string(index) + ", fChildren[" +
  93. to_string(index) + "], args);\n";
  94. this->write("%s");
  95. fFormatArgs->push_back(Compiler::FormatArg(Compiler::FormatArg::Kind::kChildProcessor,
  96. index));
  97. return;
  98. }
  99. INHERITED::writeFunctionCall(c);
  100. }
  101. void PipelineStageCodeGenerator::writeIntLiteral(const IntLiteral& i) {
  102. this->write(to_string((int32_t) i.fValue));
  103. }
  104. void PipelineStageCodeGenerator::writeVariableReference(const VariableReference& ref) {
  105. switch (ref.fVariable.fModifiers.fLayout.fBuiltin) {
  106. case SK_INCOLOR_BUILTIN:
  107. this->write("%s");
  108. fFormatArgs->push_back(Compiler::FormatArg(Compiler::FormatArg::Kind::kInput));
  109. break;
  110. case SK_OUTCOLOR_BUILTIN:
  111. this->write("%s");
  112. fFormatArgs->push_back(Compiler::FormatArg(Compiler::FormatArg::Kind::kOutput));
  113. break;
  114. case SK_MAIN_X_BUILTIN:
  115. this->write("sk_FragCoord.x");
  116. break;
  117. case SK_MAIN_Y_BUILTIN:
  118. this->write("sk_FragCoord.y");
  119. break;
  120. default:
  121. if (ref.fVariable.fModifiers.fFlags & Modifiers::kUniform_Flag) {
  122. this->write("%s");
  123. int index = 0;
  124. bool found = false;
  125. for (const auto& e : fProgram) {
  126. if (found) {
  127. break;
  128. }
  129. if (e.fKind == ProgramElement::Kind::kVar_Kind) {
  130. const VarDeclarations& decls = (const VarDeclarations&) e;
  131. for (const auto& decl : decls.fVars) {
  132. const Variable& var = *((VarDeclaration&) *decl).fVar;
  133. if (&var == &ref.fVariable) {
  134. found = true;
  135. break;
  136. }
  137. if (var.fModifiers.fFlags & Modifiers::kUniform_Flag) {
  138. ++index;
  139. }
  140. }
  141. }
  142. }
  143. SkASSERT(found);
  144. fFormatArgs->push_back(Compiler::FormatArg(Compiler::FormatArg::Kind::kUniform,
  145. index));
  146. } else {
  147. this->write(ref.fVariable.fName);
  148. }
  149. }
  150. }
  151. void PipelineStageCodeGenerator::writeIfStatement(const IfStatement& s) {
  152. if (s.fIsStatic) {
  153. this->write("@");
  154. }
  155. INHERITED::writeIfStatement(s);
  156. }
  157. void PipelineStageCodeGenerator::writeSwitchStatement(const SwitchStatement& s) {
  158. if (s.fIsStatic) {
  159. this->write("@");
  160. }
  161. INHERITED::writeSwitchStatement(s);
  162. }
  163. void PipelineStageCodeGenerator::writeFunction(const FunctionDefinition& f) {
  164. fCurrentFunction = &f.fDeclaration;
  165. if (f.fDeclaration.fName == "main") {
  166. fFunctionHeader = "";
  167. OutputStream* oldOut = fOut;
  168. StringStream buffer;
  169. fOut = &buffer;
  170. this->write("%s = %s;\n");
  171. fFormatArgs->push_back(Compiler::FormatArg(Compiler::FormatArg::Kind::kOutput));
  172. fFormatArgs->push_back(Compiler::FormatArg(Compiler::FormatArg::Kind::kInput));
  173. for (const auto& s : ((Block&) *f.fBody).fStatements) {
  174. this->writeStatement(*s);
  175. this->writeLine();
  176. }
  177. fOut = oldOut;
  178. this->write(fFunctionHeader);
  179. this->writef("%s", buffer.str().c_str());
  180. } else {
  181. INHERITED::writeFunction(f);
  182. }
  183. }
  184. bool PipelineStageCodeGenerator::writeSection(const char* name, const char* prefix) {
  185. const Section* s = fSectionAndParameterHelper.getSection(name);
  186. if (s) {
  187. this->writef("%s%s", prefix, s->fText.c_str());
  188. return true;
  189. }
  190. return false;
  191. }
  192. void PipelineStageCodeGenerator::writeProgramElement(const ProgramElement& p) {
  193. if (p.fKind == ProgramElement::kSection_Kind) {
  194. return;
  195. }
  196. if (p.fKind == ProgramElement::kVar_Kind) {
  197. const VarDeclarations& decls = (const VarDeclarations&) p;
  198. if (!decls.fVars.size()) {
  199. return;
  200. }
  201. const Variable& var = *((VarDeclaration&) *decls.fVars[0]).fVar;
  202. if (var.fModifiers.fFlags & (Modifiers::kIn_Flag | Modifiers::kUniform_Flag) ||
  203. -1 != var.fModifiers.fLayout.fBuiltin) {
  204. return;
  205. }
  206. }
  207. INHERITED::writeProgramElement(p);
  208. }
  209. } // namespace