1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2016 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #ifndef SKSL_FLOATLITERAL 9*c8dee2aaSAndroid Build Coastguard Worker #define SKSL_FLOATLITERAL 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLBuiltinTypes.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLContext.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLDefines.h" 15*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLPosition.h" 16*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/ir/SkSLExpression.h" 17*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/ir/SkSLIRNode.h" 18*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/ir/SkSLType.h" 19*c8dee2aaSAndroid Build Coastguard Worker 20*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint> 21*c8dee2aaSAndroid Build Coastguard Worker #include <cinttypes> 22*c8dee2aaSAndroid Build Coastguard Worker #include <memory> 23*c8dee2aaSAndroid Build Coastguard Worker #include <optional> 24*c8dee2aaSAndroid Build Coastguard Worker #include <string> 25*c8dee2aaSAndroid Build Coastguard Worker 26*c8dee2aaSAndroid Build Coastguard Worker namespace SkSL { 27*c8dee2aaSAndroid Build Coastguard Worker 28*c8dee2aaSAndroid Build Coastguard Worker enum class OperatorPrecedence : uint8_t; 29*c8dee2aaSAndroid Build Coastguard Worker 30*c8dee2aaSAndroid Build Coastguard Worker /** 31*c8dee2aaSAndroid Build Coastguard Worker * A literal value. These can contain ints, floats, or booleans. 32*c8dee2aaSAndroid Build Coastguard Worker */ 33*c8dee2aaSAndroid Build Coastguard Worker 34*c8dee2aaSAndroid Build Coastguard Worker class Literal : public Expression { 35*c8dee2aaSAndroid Build Coastguard Worker public: 36*c8dee2aaSAndroid Build Coastguard Worker inline static constexpr Kind kIRNodeKind = Kind::kLiteral; 37*c8dee2aaSAndroid Build Coastguard Worker Literal(Position pos,double value,const Type * type)38*c8dee2aaSAndroid Build Coastguard Worker Literal(Position pos, double value, const Type* type) 39*c8dee2aaSAndroid Build Coastguard Worker : INHERITED(pos, kIRNodeKind, type) 40*c8dee2aaSAndroid Build Coastguard Worker , fValue(value) {} 41*c8dee2aaSAndroid Build Coastguard Worker 42*c8dee2aaSAndroid Build Coastguard Worker // Makes a literal of $floatLiteral type. MakeFloat(const Context & context,Position pos,float value)43*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<Literal> MakeFloat(const Context& context, Position pos, float value) { 44*c8dee2aaSAndroid Build Coastguard Worker return std::make_unique<Literal>(pos, value, context.fTypes.fFloatLiteral.get()); 45*c8dee2aaSAndroid Build Coastguard Worker } 46*c8dee2aaSAndroid Build Coastguard Worker 47*c8dee2aaSAndroid Build Coastguard Worker // Makes a float literal of the specified type. MakeFloat(Position pos,float value,const Type * type)48*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<Literal> MakeFloat(Position pos, float value, const Type* type) { 49*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(type->isFloat()); 50*c8dee2aaSAndroid Build Coastguard Worker return std::make_unique<Literal>(pos, value, type); 51*c8dee2aaSAndroid Build Coastguard Worker } 52*c8dee2aaSAndroid Build Coastguard Worker 53*c8dee2aaSAndroid Build Coastguard Worker // Makes a literal of $intLiteral type. MakeInt(const Context & context,Position pos,SKSL_INT value)54*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<Literal> MakeInt(const Context& context, Position pos, SKSL_INT value) { 55*c8dee2aaSAndroid Build Coastguard Worker return std::make_unique<Literal>(pos, value, context.fTypes.fIntLiteral.get()); 56*c8dee2aaSAndroid Build Coastguard Worker } 57*c8dee2aaSAndroid Build Coastguard Worker 58*c8dee2aaSAndroid Build Coastguard Worker // Makes an int literal of the specified type. MakeInt(Position pos,SKSL_INT value,const Type * type)59*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<Literal> MakeInt(Position pos, SKSL_INT value, const Type* type) { 60*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(type->isInteger()); 61*c8dee2aaSAndroid Build Coastguard Worker SkASSERTF(value >= type->minimumValue(), "Value %" PRId64 " does not fit in type %s", 62*c8dee2aaSAndroid Build Coastguard Worker value, type->description().c_str()); 63*c8dee2aaSAndroid Build Coastguard Worker SkASSERTF(value <= type->maximumValue(), "Value %" PRId64 " does not fit in type %s", 64*c8dee2aaSAndroid Build Coastguard Worker value, type->description().c_str()); 65*c8dee2aaSAndroid Build Coastguard Worker return std::make_unique<Literal>(pos, value, type); 66*c8dee2aaSAndroid Build Coastguard Worker } 67*c8dee2aaSAndroid Build Coastguard Worker 68*c8dee2aaSAndroid Build Coastguard Worker // Makes a literal of boolean type. MakeBool(const Context & context,Position pos,bool value)69*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<Literal> MakeBool(const Context& context, Position pos, bool value) { 70*c8dee2aaSAndroid Build Coastguard Worker return std::make_unique<Literal>(pos, value, context.fTypes.fBool.get()); 71*c8dee2aaSAndroid Build Coastguard Worker } 72*c8dee2aaSAndroid Build Coastguard Worker 73*c8dee2aaSAndroid Build Coastguard Worker // Makes a literal of boolean type. (Functionally identical to the above, but useful if you 74*c8dee2aaSAndroid Build Coastguard Worker // don't have access to the Context.) MakeBool(Position pos,bool value,const Type * type)75*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<Literal> MakeBool(Position pos, bool value, const Type* type) { 76*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(type->isBoolean()); 77*c8dee2aaSAndroid Build Coastguard Worker return std::make_unique<Literal>(pos, value, type); 78*c8dee2aaSAndroid Build Coastguard Worker } 79*c8dee2aaSAndroid Build Coastguard Worker 80*c8dee2aaSAndroid Build Coastguard Worker // Makes a literal of the specified type, rounding as needed. Make(Position pos,double value,const Type * type)81*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<Literal> Make(Position pos, double value, const Type* type) { 82*c8dee2aaSAndroid Build Coastguard Worker if (type->isFloat()) { 83*c8dee2aaSAndroid Build Coastguard Worker return MakeFloat(pos, value, type); 84*c8dee2aaSAndroid Build Coastguard Worker } 85*c8dee2aaSAndroid Build Coastguard Worker if (type->isInteger()) { 86*c8dee2aaSAndroid Build Coastguard Worker return MakeInt(pos, value, type); 87*c8dee2aaSAndroid Build Coastguard Worker } 88*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(type->isBoolean()); 89*c8dee2aaSAndroid Build Coastguard Worker return MakeBool(pos, value, type); 90*c8dee2aaSAndroid Build Coastguard Worker } 91*c8dee2aaSAndroid Build Coastguard Worker floatValue()92*c8dee2aaSAndroid Build Coastguard Worker float floatValue() const { 93*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(this->type().isFloat()); 94*c8dee2aaSAndroid Build Coastguard Worker return (SKSL_FLOAT)fValue; 95*c8dee2aaSAndroid Build Coastguard Worker } 96*c8dee2aaSAndroid Build Coastguard Worker intValue()97*c8dee2aaSAndroid Build Coastguard Worker SKSL_INT intValue() const { 98*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(this->type().isInteger()); 99*c8dee2aaSAndroid Build Coastguard Worker return (SKSL_INT)fValue; 100*c8dee2aaSAndroid Build Coastguard Worker } 101*c8dee2aaSAndroid Build Coastguard Worker boolValue()102*c8dee2aaSAndroid Build Coastguard Worker SKSL_INT boolValue() const { 103*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(this->type().isBoolean()); 104*c8dee2aaSAndroid Build Coastguard Worker return (bool)fValue; 105*c8dee2aaSAndroid Build Coastguard Worker } 106*c8dee2aaSAndroid Build Coastguard Worker value()107*c8dee2aaSAndroid Build Coastguard Worker double value() const { 108*c8dee2aaSAndroid Build Coastguard Worker return fValue; 109*c8dee2aaSAndroid Build Coastguard Worker } 110*c8dee2aaSAndroid Build Coastguard Worker description(OperatorPrecedence)111*c8dee2aaSAndroid Build Coastguard Worker std::string description(OperatorPrecedence) const override; 112*c8dee2aaSAndroid Build Coastguard Worker 113*c8dee2aaSAndroid Build Coastguard Worker ComparisonResult compareConstant(const Expression& other) const override { 114*c8dee2aaSAndroid Build Coastguard Worker if (!other.is<Literal>() || this->type().numberKind() != other.type().numberKind()) { 115*c8dee2aaSAndroid Build Coastguard Worker return ComparisonResult::kUnknown; 116*c8dee2aaSAndroid Build Coastguard Worker } 117*c8dee2aaSAndroid Build Coastguard Worker return this->value() == other.as<Literal>().value() 118*c8dee2aaSAndroid Build Coastguard Worker ? ComparisonResult::kEqual 119*c8dee2aaSAndroid Build Coastguard Worker : ComparisonResult::kNotEqual; 120*c8dee2aaSAndroid Build Coastguard Worker } 121*c8dee2aaSAndroid Build Coastguard Worker clone(Position pos)122*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Expression> clone(Position pos) const override { 123*c8dee2aaSAndroid Build Coastguard Worker return std::make_unique<Literal>(pos, this->value(), &this->type()); 124*c8dee2aaSAndroid Build Coastguard Worker } 125*c8dee2aaSAndroid Build Coastguard Worker supportsConstantValues()126*c8dee2aaSAndroid Build Coastguard Worker bool supportsConstantValues() const override { 127*c8dee2aaSAndroid Build Coastguard Worker return true; 128*c8dee2aaSAndroid Build Coastguard Worker } 129*c8dee2aaSAndroid Build Coastguard Worker getConstantValue(int n)130*c8dee2aaSAndroid Build Coastguard Worker std::optional<double> getConstantValue(int n) const override { 131*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(n == 0); 132*c8dee2aaSAndroid Build Coastguard Worker return fValue; 133*c8dee2aaSAndroid Build Coastguard Worker } 134*c8dee2aaSAndroid Build Coastguard Worker 135*c8dee2aaSAndroid Build Coastguard Worker private: 136*c8dee2aaSAndroid Build Coastguard Worker double fValue; 137*c8dee2aaSAndroid Build Coastguard Worker 138*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = Expression; 139*c8dee2aaSAndroid Build Coastguard Worker }; 140*c8dee2aaSAndroid Build Coastguard Worker 141*c8dee2aaSAndroid Build Coastguard Worker } // namespace SkSL 142*c8dee2aaSAndroid Build Coastguard Worker 143*c8dee2aaSAndroid Build Coastguard Worker #endif 144