SkSLConstructor.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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_CONSTRUCTOR
  8. #define SKSL_CONSTRUCTOR
  9. #include "src/sksl/SkSLIRGenerator.h"
  10. #include "src/sksl/ir/SkSLExpression.h"
  11. #include "src/sksl/ir/SkSLFloatLiteral.h"
  12. #include "src/sksl/ir/SkSLIntLiteral.h"
  13. #include "src/sksl/ir/SkSLPrefixExpression.h"
  14. namespace SkSL {
  15. /**
  16. * Represents the construction of a compound type, such as "float2(x, y)".
  17. *
  18. * Vector constructors will always consist of either exactly 1 scalar, or a collection of vectors
  19. * and scalars totalling exactly the right number of scalar components.
  20. *
  21. * Matrix constructors will always consist of either exactly 1 scalar, exactly 1 matrix, or a
  22. * collection of vectors and scalars totalling exactly the right number of scalar components.
  23. */
  24. struct Constructor : public Expression {
  25. Constructor(int offset, const Type& type, std::vector<std::unique_ptr<Expression>> arguments)
  26. : INHERITED(offset, kConstructor_Kind, type)
  27. , fArguments(std::move(arguments)) {}
  28. std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
  29. const DefinitionMap& definitions) override {
  30. if (fArguments.size() == 1 && fArguments[0]->fKind == Expression::kIntLiteral_Kind) {
  31. if (fType.isFloat()) {
  32. // promote float(1) to 1.0
  33. int64_t intValue = ((IntLiteral&) *fArguments[0]).fValue;
  34. return std::unique_ptr<Expression>(new FloatLiteral(irGenerator.fContext,
  35. fOffset,
  36. intValue));
  37. } else if (fType.isInteger()) {
  38. // promote uint(1) to 1u
  39. int64_t intValue = ((IntLiteral&) *fArguments[0]).fValue;
  40. return std::unique_ptr<Expression>(new IntLiteral(fOffset,
  41. intValue,
  42. &fType));
  43. }
  44. }
  45. return nullptr;
  46. }
  47. bool hasSideEffects() const override {
  48. for (const auto& arg : fArguments) {
  49. if (arg->hasSideEffects()) {
  50. return true;
  51. }
  52. }
  53. return false;
  54. }
  55. std::unique_ptr<Expression> clone() const override {
  56. std::vector<std::unique_ptr<Expression>> cloned;
  57. for (const auto& arg : fArguments) {
  58. cloned.push_back(arg->clone());
  59. }
  60. return std::unique_ptr<Expression>(new Constructor(fOffset, fType, std::move(cloned)));
  61. }
  62. String description() const override {
  63. String result = fType.description() + "(";
  64. String separator;
  65. for (size_t i = 0; i < fArguments.size(); i++) {
  66. result += separator;
  67. result += fArguments[i]->description();
  68. separator = ", ";
  69. }
  70. result += ")";
  71. return result;
  72. }
  73. bool isConstant() const override {
  74. for (size_t i = 0; i < fArguments.size(); i++) {
  75. if (!fArguments[i]->isConstant()) {
  76. return false;
  77. }
  78. }
  79. return true;
  80. }
  81. bool compareConstant(const Context& context, const Expression& other) const override {
  82. SkASSERT(other.fKind == Expression::kConstructor_Kind && other.fType == fType);
  83. Constructor& c = (Constructor&) other;
  84. if (c.fType.kind() == Type::kVector_Kind) {
  85. bool isFloat = c.fType.columns() > 1 ? c.fType.componentType().isFloat()
  86. : c.fType.isFloat();
  87. for (int i = 0; i < fType.columns(); i++) {
  88. if (isFloat) {
  89. if (this->getFVecComponent(i) != c.getFVecComponent(i)) {
  90. return false;
  91. }
  92. } else if (this->getIVecComponent(i) != c.getIVecComponent(i)) {
  93. return false;
  94. }
  95. }
  96. return true;
  97. }
  98. // shouldn't be possible to have a constant constructor that isn't a vector or matrix;
  99. // a constant scalar constructor should have been collapsed down to the appropriate
  100. // literal
  101. SkASSERT(fType.kind() == Type::kMatrix_Kind);
  102. for (int col = 0; col < fType.columns(); col++) {
  103. for (int row = 0; row < fType.rows(); row++) {
  104. if (getMatComponent(col, row) != c.getMatComponent(col, row)) {
  105. return false;
  106. }
  107. }
  108. }
  109. return true;
  110. }
  111. template<typename type>
  112. type getVecComponent(int index) const {
  113. SkASSERT(fType.kind() == Type::kVector_Kind);
  114. if (fArguments.size() == 1 && fArguments[0]->fType.kind() == Type::kScalar_Kind) {
  115. if (std::is_floating_point<type>::value) {
  116. return fArguments[0]->getConstantFloat();
  117. } else {
  118. return fArguments[0]->getConstantInt();
  119. }
  120. }
  121. int current = 0;
  122. for (const auto& arg : fArguments) {
  123. SkASSERT(current <= index);
  124. if (arg->fType.kind() == Type::kScalar_Kind) {
  125. if (index == current) {
  126. if (std::is_floating_point<type>::value) {
  127. return arg.get()->getConstantFloat();
  128. } else {
  129. return arg.get()->getConstantInt();
  130. }
  131. }
  132. current++;
  133. } else if (arg->fKind == kConstructor_Kind) {
  134. if (current + arg->fType.columns() > index) {
  135. return ((const Constructor&) *arg).getVecComponent<type>(index - current);
  136. }
  137. current += arg->fType.columns();
  138. } else {
  139. if (current + arg->fType.columns() > index) {
  140. SkASSERT(arg->fKind == kPrefix_Kind);
  141. const PrefixExpression& p = (PrefixExpression&) *arg;
  142. const Constructor& c = (const Constructor&) *p.fOperand;
  143. return -c.getVecComponent<type>(index - current);
  144. }
  145. current += arg->fType.columns();
  146. }
  147. }
  148. ABORT("failed to find vector component %d in %s\n", index, description().c_str());
  149. }
  150. SKSL_FLOAT getFVecComponent(int n) const override {
  151. return this->getVecComponent<SKSL_FLOAT>(n);
  152. }
  153. /**
  154. * For a literal vector expression, return the integer value of the n'th vector component. It is
  155. * an error to call this method on an expression which is not a literal vector.
  156. */
  157. SKSL_INT getIVecComponent(int n) const override {
  158. return this->getVecComponent<SKSL_INT>(n);
  159. }
  160. SKSL_FLOAT getMatComponent(int col, int row) const override {
  161. SkASSERT(this->isConstant());
  162. SkASSERT(fType.kind() == Type::kMatrix_Kind);
  163. SkASSERT(col < fType.columns() && row < fType.rows());
  164. if (fArguments.size() == 1) {
  165. if (fArguments[0]->fType.kind() == Type::kScalar_Kind) {
  166. // single scalar argument, so matrix is of the form:
  167. // x 0 0
  168. // 0 x 0
  169. // 0 0 x
  170. // return x if col == row
  171. return col == row ? fArguments[0]->getConstantFloat() : 0.0;
  172. }
  173. if (fArguments[0]->fType.kind() == Type::kMatrix_Kind) {
  174. SkASSERT(fArguments[0]->fKind == Expression::kConstructor_Kind);
  175. // single matrix argument. make sure we're within the argument's bounds.
  176. const Type& argType = ((Constructor&) *fArguments[0]).fType;
  177. if (col < argType.columns() && row < argType.rows()) {
  178. // within bounds, defer to argument
  179. return ((Constructor&) *fArguments[0]).getMatComponent(col, row);
  180. }
  181. // out of bounds
  182. return 0.0;
  183. }
  184. }
  185. int currentIndex = 0;
  186. int targetIndex = col * fType.rows() + row;
  187. for (const auto& arg : fArguments) {
  188. SkASSERT(targetIndex >= currentIndex);
  189. SkASSERT(arg->fType.rows() == 1);
  190. if (currentIndex + arg->fType.columns() > targetIndex) {
  191. if (arg->fType.columns() == 1) {
  192. return arg->getConstantFloat();
  193. } else {
  194. return arg->getFVecComponent(targetIndex - currentIndex);
  195. }
  196. }
  197. currentIndex += arg->fType.columns();
  198. }
  199. ABORT("can't happen, matrix component out of bounds");
  200. }
  201. std::vector<std::unique_ptr<Expression>> fArguments;
  202. typedef Expression INHERITED;
  203. };
  204. } // namespace
  205. #endif