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