blob: 208031abbae150a7af0f4655fde6ceaa16c21d65 [file] [log] [blame]
ethannicholasb3058bd2016-07-01 08:22:01 -07001/*
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 */
Greg Daniel64773e62016-11-22 09:44:03 -05007
ethannicholasb3058bd2016-07-01 08:22:01 -07008#ifndef SKSL_CONSTRUCTOR
9#define SKSL_CONSTRUCTOR
10
11#include "SkSLExpression.h"
Ethan Nicholas86a43402017-01-19 13:32:00 -050012#include "SkSLFloatLiteral.h"
13#include "SkSLIntLiteral.h"
14#include "SkSLIRGenerator.h"
ethannicholasb3058bd2016-07-01 08:22:01 -070015
16namespace SkSL {
17
18/**
19 * Represents the construction of a compound type, such as "vec2(x, y)".
Ethan Nicholas84645e32017-02-09 13:57:14 -050020 *
21 * Vector constructors will always consist of either exactly 1 scalar, or a collection of vectors
22 * and scalars totalling exactly the right number of scalar components.
23 *
24 * Matrix constructors will always consist of either exactly 1 scalar, exactly 1 matrix, or a
25 * collection of vectors and scalars totalling exactly the right number of scalar components.
ethannicholasb3058bd2016-07-01 08:22:01 -070026 */
27struct Constructor : public Expression {
Greg Daniel64773e62016-11-22 09:44:03 -050028 Constructor(Position position, const Type& type,
ethannicholasb3058bd2016-07-01 08:22:01 -070029 std::vector<std::unique_ptr<Expression>> arguments)
ethannicholasd598f792016-07-25 10:08:54 -070030 : INHERITED(position, kConstructor_Kind, type)
ethannicholasb3058bd2016-07-01 08:22:01 -070031 , fArguments(std::move(arguments)) {}
32
Ethan Nicholascb670962017-04-20 19:31:52 -040033 std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
34 const DefinitionMap& definitions) override {
35 if (fArguments.size() == 1 && fArguments[0]->fKind == Expression::kIntLiteral_Kind) {
36 if (fType == *irGenerator.fContext.fFloat_Type) {
37 // promote float(1) to 1.0
38 int64_t intValue = ((IntLiteral&) *fArguments[0]).fValue;
39 return std::unique_ptr<Expression>(new FloatLiteral(irGenerator.fContext,
40 fPosition,
41 intValue));
42 } else if (fType == *irGenerator.fContext.fUInt_Type) {
43 // promote uint(1) to 1u
44 int64_t intValue = ((IntLiteral&) *fArguments[0]).fValue;
45 return std::unique_ptr<Expression>(new IntLiteral(irGenerator.fContext,
46 fPosition,
47 intValue,
48 &fType));
49 }
Ethan Nicholas86a43402017-01-19 13:32:00 -050050 }
51 return nullptr;
52 }
53
Ethan Nicholascb670962017-04-20 19:31:52 -040054 bool hasSideEffects() const override {
55 for (const auto& arg : fArguments) {
56 if (arg->hasSideEffects()) {
57 return true;
58 }
59 }
60 return false;
61 }
62
Ethan Nicholas0df1b042017-03-31 13:56:23 -040063 String description() const override {
64 String result = fType.description() + "(";
65 String separator;
ethannicholasb3058bd2016-07-01 08:22:01 -070066 for (size_t i = 0; i < fArguments.size(); i++) {
67 result += separator;
68 result += fArguments[i]->description();
69 separator = ", ";
70 }
71 result += ")";
72 return result;
73 }
74
75 bool isConstant() const override {
76 for (size_t i = 0; i < fArguments.size(); i++) {
77 if (!fArguments[i]->isConstant()) {
78 return false;
79 }
80 }
81 return true;
82 }
83
Ethan Nicholascb670962017-04-20 19:31:52 -040084 const Expression& getVecComponent(int index) const {
85 ASSERT(fType.kind() == Type::kVector_Kind);
86 if (fArguments.size() == 1 && fArguments[0]->fType.kind() == Type::kScalar_Kind) {
87 return *fArguments[0];
88 }
89 int current = 0;
90 for (const auto& arg : fArguments) {
91 ASSERT(current <= index);
92 if (arg->fType.kind() == Type::kScalar_Kind) {
93 if (index == current) {
94 return *arg;
95 }
96 current++;
97 } else {
98 ASSERT(arg->fType.kind() == Type::kVector_Kind);
99 ASSERT(arg->fKind == Expression::kConstructor_Kind);
100 if (current + arg->fType.columns() > index) {
101 return ((const Constructor&) *arg).getVecComponent(index - current);
102 }
103 current += arg->fType.columns();
104 }
105 }
106 ABORT("failed to find vector component %d in %s\n", index, description().c_str());
107 }
108
109 double getFVecComponent(int index) const {
110 const Expression& c = this->getVecComponent(index);
111 ASSERT(c.fKind == Expression::kFloatLiteral_Kind);
112 return ((FloatLiteral&) c).fValue;
113 }
114
115 int64_t getIVecComponent(int index) const {
116 const Expression& c = this->getVecComponent(index);
117 ASSERT(c.fKind == Expression::kIntLiteral_Kind);
118 return ((IntLiteral&) c).fValue;
119 }
120
Ethan Nicholas86a43402017-01-19 13:32:00 -0500121 std::vector<std::unique_ptr<Expression>> fArguments;
ethannicholasb3058bd2016-07-01 08:22:01 -0700122
123 typedef Expression INHERITED;
124};
125
126} // namespace
127
128#endif