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