Flutter Engine
The Flutter Engine
SkSLConstructorCompoundCast.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2021 Google LLC
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
9
18
19#include <cstddef>
20#include <iterator>
21#include <optional>
22
23namespace SkSL {
24
25static std::unique_ptr<Expression> cast_constant_composite(const Context& context,
27 const Type& destType,
28 std::unique_ptr<Expression> constCtor) {
29 const Type& scalarType = destType.componentType();
30
31 // We generate nicer code for splats and diagonal matrices by handling them separately instead
32 // of relying on the constant-subexpression code below. This is not truly necessary but it makes
33 // our output look a little better; human beings prefer `half4(0)` to `half4(0, 0, 0, 0)`.
34 if (constCtor->is<ConstructorSplat>()) {
35 // This is a typecast of a splat containing a constant value, e.g. `half4(7)`. We can
36 // replace it with a splat of a different type, e.g. `int4(7)`.
37 ConstructorSplat& splat = constCtor->as<ConstructorSplat>();
39 context, pos, destType,
40 ConstructorScalarCast::Make(context, pos, scalarType, std::move(splat.argument())));
41 }
42
43 if (constCtor->is<ConstructorDiagonalMatrix>() && destType.isMatrix()) {
44 // This is a typecast of a constant diagonal matrix, e.g. `float3x3(2)`. We can replace it
45 // with a diagonal matrix of a different type, e.g. `half3x3(2)`.
46 ConstructorDiagonalMatrix& matrixCtor = constCtor->as<ConstructorDiagonalMatrix>();
48 context, pos, destType,
49 ConstructorScalarCast::Make(context, pos, scalarType,
50 std::move(matrixCtor.argument())));
51 }
52
53 // Create a compound Constructor(literal, ...) which typecasts each scalar value inside.
54 size_t numSlots = destType.slotCount();
55 SkASSERT(numSlots == constCtor->type().slotCount());
56
57 double typecastArgs[16];
58 SkASSERT(numSlots <= std::size(typecastArgs));
59 for (size_t index = 0; index < numSlots; ++index) {
60 std::optional<double> slotVal = constCtor->getConstantValue(index);
61 if (scalarType.checkForOutOfRangeLiteral(context, *slotVal, constCtor->fPosition)) {
62 // We've reported an error because the literal is out of range for this type. Zero out
63 // the value to avoid a cascade of errors.
64 *slotVal = 0.0;
65 }
66 typecastArgs[index] = *slotVal;
67 }
68
69 return ConstructorCompound::MakeFromConstants(context, pos, destType, typecastArgs);
70}
71
72std::unique_ptr<Expression> ConstructorCompoundCast::Make(const Context& context,
74 const Type& type,
75 std::unique_ptr<Expression> arg) {
76 // Only vectors or matrices of the same dimensions are allowed.
79 SkASSERT(arg->type().isVector() == type.isVector());
80 SkASSERT(arg->type().isMatrix() == type.isMatrix());
81 SkASSERT(type.columns() == arg->type().columns());
82 SkASSERT(type.rows() == arg->type().rows());
83
84 // If this is a no-op cast, return the expression as-is.
85 if (type.matches(arg->type())) {
86 arg->setPosition(pos);
87 return arg;
88 }
89 // Look up the value of constant variables. This allows constant-expressions like
90 // `int4(colorGreen)` to be replaced with the compile-time constant `int4(0, 1, 0, 1)`.
92
93 // We can cast a vector of compile-time constants at compile-time.
95 return cast_constant_composite(context, pos, type, std::move(arg));
96 }
97 return std::make_unique<ConstructorCompoundCast>(pos, type, std::move(arg));
98}
99
100} // namespace SkSL
SkPoint pos
#define SkASSERT(cond)
Definition: SkAssert.h:116
GLenum type
static std::unique_ptr< Expression > MakeConstantValueForVariable(Position pos, std::unique_ptr< Expression > expr)
static std::unique_ptr< Expression > Make(const Context &context, Position pos, const Type &type, std::unique_ptr< Expression > arg)
static std::unique_ptr< Expression > MakeFromConstants(const Context &context, Position pos, const Type &type, const double values[])
static std::unique_ptr< Expression > Make(const Context &context, Position pos, const Type &type, std::unique_ptr< Expression > arg)
static std::unique_ptr< Expression > Make(const Context &context, Position pos, const Type &type, std::unique_ptr< Expression > arg)
static std::unique_ptr< Expression > Make(const Context &context, Position pos, const Type &type, std::unique_ptr< Expression > arg)
const Type & type() const
const T & as() const
Definition: SkSLIRNode.h:133
std::unique_ptr< Expression > & argument()
virtual bool isVector() const
Definition: SkSLType.h:524
bool isAllowedInES2(const Context &context) const
virtual int rows() const
Definition: SkSLType.h:438
virtual const Type & componentType() const
Definition: SkSLType.h:404
bool matches(const Type &other) const
Definition: SkSLType.h:269
virtual bool isMatrix() const
Definition: SkSLType.h:528
virtual int columns() const
Definition: SkSLType.h:429
virtual size_t slotCount() const
Definition: SkSLType.h:457
bool checkForOutOfRangeLiteral(const Context &context, const Expression &expr) const
bool IsCompileTimeConstant(const Expression &expr)
static std::unique_ptr< Expression > cast_constant_composite(const Context &context, Position pos, const Type &destType, std::unique_ptr< Expression > constCtor)
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259