Flutter Engine
The Flutter Engine
SkSLConstructorArray.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
14#include "src/sksl/SkSLString.h"
17
18#include <algorithm>
19#include <string>
20
21namespace SkSL {
22
23std::unique_ptr<Expression> ConstructorArray::Convert(const Context& context,
25 const Type& type,
27 SkASSERTF(type.isArray() && type.columns() > 0, "%s", type.description().c_str());
28
29 // ES2 doesn't support first-class array types.
30 if (context.fConfig->strictES2Mode()) {
31 context.fErrors->error(pos, "construction of array type '" + type.displayName() +
32 "' is not supported");
33 return nullptr;
34 }
35
36 // An array of atomics cannot be constructed.
38 context.fErrors->error(
39 pos,
40 String::printf("construction of array type '%s' with atomic member is not allowed",
41 type.displayName().c_str()));
42 return nullptr;
43 }
44
45 // If there is a single argument containing an array of matching size and the types are
46 // coercible, this is actually a cast. i.e., `half[10](myFloat10Array)`. This isn't a GLSL
47 // feature, but the Pipeline stage code generator needs this functionality so that code which
48 // was originally compiled with "allow narrowing conversions" enabled can be later recompiled
49 // without narrowing conversions (we patch over these conversions with an explicit cast).
50 if (args.size() == 1) {
51 const Expression& expr = *args.front();
52 const Type& exprType = expr.type();
53
54 if (exprType.isArray() && exprType.canCoerceTo(type, /*allowNarrowing=*/true)) {
55 return ConstructorArrayCast::Make(context, pos, type, std::move(args.front()));
56 }
57 }
58
59 // Check that the number of constructor arguments matches the array size.
60 if (type.columns() != args.size()) {
61 context.fErrors->error(pos, String::printf("invalid arguments to '%s' constructor "
62 "(expected %d elements, but found %d)", type.displayName().c_str(), type.columns(),
63 args.size()));
64 return nullptr;
65 }
66
67 // Convert each constructor argument to the array's component type.
68 const Type& baseType = type.componentType();
69 for (std::unique_ptr<Expression>& argument : args) {
70 argument = baseType.coerceExpression(std::move(argument), context);
71 if (!argument) {
72 return nullptr;
73 }
74 }
75
76 return ConstructorArray::Make(context, pos, type, std::move(args));
77}
78
79std::unique_ptr<Expression> ConstructorArray::Make(const Context& context,
81 const Type& type,
83 SkASSERT(!context.fConfig->strictES2Mode());
85 SkASSERT(type.columns() == args.size());
87 SkASSERT(std::all_of(args.begin(), args.end(), [&](const std::unique_ptr<Expression>& arg) {
88 return type.componentType().matches(arg->type());
89 }));
90
91 return std::make_unique<ConstructorArray>(pos, type, std::move(args));
92}
93
94} // namespace SkSL
SkPoint pos
#define SkASSERT(cond)
Definition: SkAssert.h:116
#define SkASSERTF(cond, fmt,...)
Definition: SkAssert.h:117
GLenum type
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, ExpressionArray args)
static std::unique_ptr< Expression > Convert(const Context &context, Position pos, const Type &type, ExpressionArray args)
ErrorReporter * fErrors
Definition: SkSLContext.h:36
ProgramConfig * fConfig
Definition: SkSLContext.h:33
void error(Position position, std::string_view msg)
const Type & type() const
virtual bool isArray() const
Definition: SkSLType.h:532
bool isAllowedInES2(const Context &context) const
std::unique_ptr< Expression > coerceExpression(std::unique_ptr< Expression > expr, const Context &context) const
virtual const Type & componentType() const
Definition: SkSLType.h:404
virtual int columns() const
Definition: SkSLType.h:429
std::string description() const override
Definition: SkSLType.h:238
virtual bool isOrContainsAtomic() const
Definition: SkSLType.h:586
bool canCoerceTo(const Type &other, bool allowNarrowing) const
Definition: SkSLType.h:388
std::string displayName() const
Definition: SkSLType.h:234
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
std::string printf(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: SkSLString.cpp:83