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