• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/ir/SkSLChildCall.h"
9 
10 #include "include/core/SkTypes.h"
11 #include "include/private/SkSLString.h"
12 #include "include/private/base/SkTArray.h"
13 #include "include/sksl/SkSLOperator.h"
14 #include "src/sksl/SkSLBuiltinTypes.h"
15 #include "src/sksl/SkSLContext.h"
16 #include "src/sksl/ir/SkSLType.h"
17 #include "src/sksl/ir/SkSLVariable.h"
18 
19 namespace SkSL {
20 
clone(Position pos) const21 std::unique_ptr<Expression> ChildCall::clone(Position pos) const {
22     return std::make_unique<ChildCall>(pos, &this->type(), &this->child(),
23                                        this->arguments().clone());
24 }
25 
description(OperatorPrecedence) const26 std::string ChildCall::description(OperatorPrecedence) const {
27     std::string result = std::string(this->child().name()) + ".eval(";
28     auto separator = SkSL::String::Separator();
29     for (const std::unique_ptr<Expression>& arg : this->arguments()) {
30         result += separator();
31         result += arg->description(OperatorPrecedence::kSequence);
32     }
33     result += ")";
34     return result;
35 }
36 
call_signature_is_valid(const Context & context,const Variable & child,const ExpressionArray & arguments)37 [[maybe_unused]] static bool call_signature_is_valid(const Context& context,
38                                                      const Variable& child,
39                                                      const ExpressionArray& arguments) {
40     const Type* half4 = context.fTypes.fHalf4.get();
41     const Type* float2 = context.fTypes.fFloat2.get();
42 
43     auto params = [&]() -> SkSTArray<2, const Type*> {
44         switch (child.type().typeKind()) {
45             case Type::TypeKind::kBlender:     return { half4, half4 };
46             case Type::TypeKind::kColorFilter: return { half4 };
47             case Type::TypeKind::kShader:      return { float2 };
48             default:
49                 SkUNREACHABLE;
50         }
51     }();
52 
53     if (params.size() != arguments.size()) {
54         return false;
55     }
56     for (int i = 0; i < arguments.size(); i++) {
57         if (!arguments[i]->type().matches(*params[i])) {
58             return false;
59         }
60     }
61     return true;
62 }
63 
Make(const Context & context,Position pos,const Type * returnType,const Variable & child,ExpressionArray arguments)64 std::unique_ptr<Expression> ChildCall::Make(const Context& context,
65                                             Position pos,
66                                             const Type* returnType,
67                                             const Variable& child,
68                                             ExpressionArray arguments) {
69     SkASSERT(call_signature_is_valid(context, child, arguments));
70     return std::make_unique<ChildCall>(pos, returnType, &child, std::move(arguments));
71 }
72 
73 }  // namespace SkSL
74