SkSLSectionAndParameterHelper.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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_SECTIONANDPARAMETERHELPER
  8. #define SKSL_SECTIONANDPARAMETERHELPER
  9. #include "src/sksl/SkSLErrorReporter.h"
  10. #include "src/sksl/ir/SkSLProgram.h"
  11. #include "src/sksl/ir/SkSLSection.h"
  12. #include "src/sksl/ir/SkSLVarDeclarations.h"
  13. #include <unordered_map>
  14. #include <vector>
  15. namespace SkSL {
  16. #define CLASS_SECTION "class"
  17. #define CLONE_SECTION "clone"
  18. #define CONSTRUCTOR_SECTION "constructor"
  19. #define CONSTRUCTOR_CODE_SECTION "constructorCode"
  20. #define CONSTRUCTOR_PARAMS_SECTION "constructorParams"
  21. #define COORD_TRANSFORM_SECTION "coordTransform"
  22. #define CPP_SECTION "cpp"
  23. #define CPP_END_SECTION "cppEnd"
  24. #define HEADER_SECTION "header"
  25. #define HEADER_END_SECTION "headerEnd"
  26. #define EMIT_CODE_SECTION "emitCode"
  27. #define FIELDS_SECTION "fields"
  28. #define INITIALIZERS_SECTION "initializers"
  29. #define MAKE_SECTION "make"
  30. #define OPTIMIZATION_FLAGS_SECTION "optimizationFlags"
  31. #define SAMPLER_PARAMS_SECTION "samplerParams"
  32. #define SET_DATA_SECTION "setData"
  33. #define TEST_CODE_SECTION "test"
  34. class SectionAndParameterHelper {
  35. public:
  36. SectionAndParameterHelper(const Program& program, ErrorReporter& errors) {
  37. for (const auto& p : program) {
  38. switch (p.fKind) {
  39. case ProgramElement::kVar_Kind: {
  40. const VarDeclarations& decls = (const VarDeclarations&) p;
  41. for (const auto& raw : decls.fVars) {
  42. const VarDeclaration& decl = (VarDeclaration&) *raw;
  43. if (IsParameter(*decl.fVar)) {
  44. fParameters.push_back(decl.fVar);
  45. }
  46. }
  47. break;
  48. }
  49. case ProgramElement::kSection_Kind: {
  50. const Section& s = (const Section&) p;
  51. if (IsSupportedSection(s.fName.c_str())) {
  52. if (SectionRequiresArgument(s.fName.c_str()) && !s.fArgument.size()) {
  53. errors.error(s.fOffset,
  54. ("section '@" + s.fName +
  55. "' requires one parameter").c_str());
  56. }
  57. if (!SectionAcceptsArgument(s.fName.c_str()) && s.fArgument.size()) {
  58. errors.error(s.fOffset,
  59. ("section '@" + s.fName + "' has no parameters").c_str());
  60. }
  61. } else {
  62. errors.error(s.fOffset,
  63. ("unsupported section '@" + s.fName + "'").c_str());
  64. }
  65. if (!SectionPermitsDuplicates(s.fName.c_str()) &&
  66. fSections.find(s.fName) != fSections.end()) {
  67. errors.error(s.fOffset,
  68. ("duplicate section '@" + s.fName + "'").c_str());
  69. }
  70. fSections[s.fName].push_back(&s);
  71. break;
  72. }
  73. default:
  74. break;
  75. }
  76. }
  77. }
  78. const Section* getSection(const char* name) {
  79. SkASSERT(!SectionPermitsDuplicates(name));
  80. auto found = fSections.find(name);
  81. if (found == fSections.end()) {
  82. return nullptr;
  83. }
  84. SkASSERT(found->second.size() == 1);
  85. return found->second[0];
  86. }
  87. std::vector<const Section*> getSections(const char* name) {
  88. auto found = fSections.find(name);
  89. if (found == fSections.end()) {
  90. return std::vector<const Section*>();
  91. }
  92. return found->second;
  93. }
  94. const std::vector<const Variable*>& getParameters() {
  95. return fParameters;
  96. }
  97. static bool IsParameter(const Variable& var) {
  98. return (var.fModifiers.fFlags & Modifiers::kIn_Flag) &&
  99. -1 == var.fModifiers.fLayout.fBuiltin;
  100. }
  101. static bool IsSupportedSection(const char* name) {
  102. return !strcmp(name, CLASS_SECTION) ||
  103. !strcmp(name, CLONE_SECTION) ||
  104. !strcmp(name, CONSTRUCTOR_SECTION) ||
  105. !strcmp(name, CONSTRUCTOR_CODE_SECTION) ||
  106. !strcmp(name, CONSTRUCTOR_PARAMS_SECTION) ||
  107. !strcmp(name, COORD_TRANSFORM_SECTION) ||
  108. !strcmp(name, CPP_SECTION) ||
  109. !strcmp(name, CPP_END_SECTION) ||
  110. !strcmp(name, EMIT_CODE_SECTION) ||
  111. !strcmp(name, FIELDS_SECTION) ||
  112. !strcmp(name, HEADER_SECTION) ||
  113. !strcmp(name, HEADER_END_SECTION) ||
  114. !strcmp(name, INITIALIZERS_SECTION) ||
  115. !strcmp(name, MAKE_SECTION) ||
  116. !strcmp(name, OPTIMIZATION_FLAGS_SECTION) ||
  117. !strcmp(name, SAMPLER_PARAMS_SECTION) ||
  118. !strcmp(name, SET_DATA_SECTION) ||
  119. !strcmp(name, TEST_CODE_SECTION);
  120. }
  121. static bool SectionAcceptsArgument(const char* name) {
  122. return !strcmp(name, COORD_TRANSFORM_SECTION) ||
  123. !strcmp(name, SAMPLER_PARAMS_SECTION) ||
  124. !strcmp(name, SET_DATA_SECTION) ||
  125. !strcmp(name, TEST_CODE_SECTION);
  126. }
  127. static bool SectionRequiresArgument(const char* name) {
  128. return !strcmp(name, SAMPLER_PARAMS_SECTION) ||
  129. !strcmp(name, SET_DATA_SECTION) ||
  130. !strcmp(name, TEST_CODE_SECTION);
  131. }
  132. static bool SectionPermitsDuplicates(const char* name) {
  133. return !strcmp(name, COORD_TRANSFORM_SECTION) ||
  134. !strcmp(name, SAMPLER_PARAMS_SECTION);
  135. }
  136. private:
  137. std::vector<const Variable*> fParameters;
  138. std::unordered_map<String, std::vector<const Section*>> fSections;
  139. };
  140. } // namespace SkSL
  141. #endif