SkSLCPPCodeGenerator.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /*
  2. * Copyright 2017 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_CPPCODEGENERATOR
  8. #define SKSL_CPPCODEGENERATOR
  9. #include "src/sksl/SkSLGLSLCodeGenerator.h"
  10. #include "src/sksl/SkSLSectionAndParameterHelper.h"
  11. #include <set>
  12. namespace SkSL {
  13. class CPPCodeGenerator : public GLSLCodeGenerator {
  14. public:
  15. CPPCodeGenerator(const Context* context, const Program* program, ErrorReporter* errors,
  16. String name, OutputStream* out);
  17. bool generateCode() override;
  18. private:
  19. void writef(const char* s, va_list va) SKSL_PRINTF_LIKE(2, 0);
  20. void writef(const char* s, ...) SKSL_PRINTF_LIKE(2, 3);
  21. bool writeSection(const char* name, const char* prefix = "");
  22. void writeHeader() override;
  23. bool usesPrecisionModifiers() const override;
  24. String getTypeName(const Type& type) override;
  25. void writeBinaryExpression(const BinaryExpression& b, Precedence parentPrecedence) override;
  26. void writeIndexExpression(const IndexExpression& i) override;
  27. void writeIntLiteral(const IntLiteral& i) override;
  28. void writeSwizzle(const Swizzle& swizzle) override;
  29. void writeFieldAccess(const FieldAccess& access) override;
  30. void writeVariableReference(const VariableReference& ref) override;
  31. String getSamplerHandle(const Variable& var);
  32. void writeIfStatement(const IfStatement& s) override;
  33. void writeReturnStatement(const ReturnStatement& s) override;
  34. void writeSwitchStatement(const SwitchStatement& s) override;
  35. void writeFunctionCall(const FunctionCall& c) override;
  36. void writeFunction(const FunctionDefinition& f) override;
  37. void writeSetting(const Setting& s) override;
  38. void writeProgramElement(const ProgramElement& p) override;
  39. void addUniform(const Variable& var);
  40. // writes a printf escape that will be filled in at runtime by the given C++ expression string
  41. void writeRuntimeValue(const Type& type, const Layout& layout, const String& cppCode);
  42. void writeVarInitializer(const Variable& var, const Expression& value) override;
  43. void writeInputVars() override;
  44. void writePrivateVars();
  45. void writePrivateVarValues();
  46. void writeCodeAppend(const String& code);
  47. bool writeEmitCode(std::vector<const Variable*>& uniforms);
  48. void writeSetData(std::vector<const Variable*>& uniforms);
  49. void writeGetKey();
  50. void writeOnTextureSampler();
  51. void writeClone();
  52. void writeTest();
  53. // If the returned C++ is included in the generated code, then the variable name stored in
  54. // cppVar will refer to a valid SkString that matches the Expression. Successful returns leave
  55. // the output buffer (and related state) unmodified.
  56. //
  57. // In the simplest cases, this will return "SkString {cppVar}(\"{e}\");", while more advanced
  58. // cases will properly insert format arguments.
  59. String convertSKSLExpressionToCPP(const Expression& e, const String& cppVar);
  60. // Process accumulated sksl to split it into appended code sections, properly interleaved with
  61. // the extra emit code blocks, based on statement/block locations and the inserted tokens
  62. // from newExtraEmitCodeBlock(). It is necessary to split the sksl after the program has been
  63. // fully walked since many elements redirect fOut to simultaneously build header sections and
  64. // bodies that are then concatenated; due to this it is not possible to split the sksl emission
  65. // on the fly.
  66. void flushEmittedCode();
  67. // Start a new extra emit code block for accumulating C++ code. This will insert a token into
  68. // the sksl stream to mark the fence between previous complete sksl statements and where the
  69. // C++ code added to the new block will be added to emitCode(). These tokens are removed by
  70. // flushEmittedCode() as it consumes them before passing pure sksl to writeCodeAppend().
  71. void newExtraEmitCodeBlock();
  72. // Append CPP code to the current extra emit code block.
  73. void addExtraEmitCodeLine(const String& toAppend);
  74. int getChildFPIndex(const Variable& var) const;
  75. String fName;
  76. String fFullName;
  77. SectionAndParameterHelper fSectionAndParameterHelper;
  78. std::vector<String> fExtraEmitCodeBlocks;
  79. std::vector<String> fFormatArgs;
  80. std::set<int> fWrittenTransformedCoords;
  81. // if true, we are writing a C++ expression instead of a GLSL expression
  82. bool fCPPMode = false;
  83. bool fInMain = false;
  84. // if not null, we are accumulating SkSL for emitCode into fOut, which
  85. // replaced the original buffer with a StringStream. The original buffer is
  86. // stored here for restoration.
  87. OutputStream* fCPPBuffer = nullptr;
  88. typedef GLSLCodeGenerator INHERITED;
  89. };
  90. }
  91. #endif