xref: /third_party/skia/src/sksl/ir/SkSLChildCall.cpp (revision cb93a386)
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
8#include "src/sksl/SkSLContext.h"
9#include "src/sksl/ir/SkSLChildCall.h"
10
11namespace SkSL {
12
13bool ChildCall::hasProperty(Property property) const {
14    for (const auto& arg : this->arguments()) {
15        if (arg->hasProperty(property)) {
16            return true;
17        }
18    }
19    return false;
20}
21
22std::unique_ptr<Expression> ChildCall::clone() const {
23    ExpressionArray cloned;
24    cloned.reserve_back(this->arguments().size());
25    for (const std::unique_ptr<Expression>& arg : this->arguments()) {
26        cloned.push_back(arg->clone());
27    }
28    return std::make_unique<ChildCall>(fLine, &this->type(), &this->child(), std::move(cloned));
29}
30
31String ChildCall::description() const {
32    String result = String(this->child().name()) + ".eval(";
33    String separator;
34    for (const std::unique_ptr<Expression>& arg : this->arguments()) {
35        result += separator;
36        result += arg->description();
37        separator = ", ";
38    }
39    result += ")";
40    return result;
41}
42
43[[maybe_unused]] static bool call_signature_is_valid(const Context& context,
44                                                     const Variable& child,
45                                                     const ExpressionArray& arguments) {
46    const Type* half4 = context.fTypes.fHalf4.get();
47    const Type* float2 = context.fTypes.fFloat2.get();
48
49    auto params = [&]() -> SkSTArray<2, const Type*> {
50        switch (child.type().typeKind()) {
51            case Type::TypeKind::kBlender:     return { half4, half4 };
52            case Type::TypeKind::kColorFilter: return { half4 };
53            case Type::TypeKind::kShader:      return { float2 };
54            default:
55                SkUNREACHABLE;
56        }
57    }();
58
59    if (params.size() != arguments.size()) {
60        return false;
61    }
62    for (size_t i = 0; i < arguments.size(); i++) {
63        if (arguments[i]->type() != *params[i]) {
64            return false;
65        }
66    }
67    return true;
68}
69
70std::unique_ptr<Expression> ChildCall::Make(const Context& context,
71                                            int line,
72                                            const Type* returnType,
73                                            const Variable& child,
74                                            ExpressionArray arguments) {
75    SkASSERT(call_signature_is_valid(context, child, arguments));
76    return std::make_unique<ChildCall>(line, returnType, &child, std::move(arguments));
77}
78
79}  // namespace SkSL
80