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#ifndef SKSL_CONSTRUCTOR_SPLAT 9cb93a386Sopenharmony_ci#define SKSL_CONSTRUCTOR_SPLAT 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_ci#include "src/sksl/SkSLContext.h" 12cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLConstructor.h" 13cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLExpression.h" 14cb93a386Sopenharmony_ci 15cb93a386Sopenharmony_ci#include <memory> 16cb93a386Sopenharmony_ci 17cb93a386Sopenharmony_cinamespace SkSL { 18cb93a386Sopenharmony_ci 19cb93a386Sopenharmony_ci/** 20cb93a386Sopenharmony_ci * Represents the construction of a vector splat, such as `half3(n)`. 21cb93a386Sopenharmony_ci * 22cb93a386Sopenharmony_ci * These always contain exactly 1 scalar. 23cb93a386Sopenharmony_ci */ 24cb93a386Sopenharmony_ciclass ConstructorSplat final : public SingleArgumentConstructor { 25cb93a386Sopenharmony_cipublic: 26cb93a386Sopenharmony_ci inline static constexpr Kind kExpressionKind = Kind::kConstructorSplat; 27cb93a386Sopenharmony_ci 28cb93a386Sopenharmony_ci ConstructorSplat(int line, const Type& type, std::unique_ptr<Expression> arg) 29cb93a386Sopenharmony_ci : INHERITED(line, kExpressionKind, &type, std::move(arg)) {} 30cb93a386Sopenharmony_ci 31cb93a386Sopenharmony_ci ConstructorSplat(const Expression& scalar, const Type& type) 32cb93a386Sopenharmony_ci : ConstructorSplat(scalar.fLine, type, scalar.clone()) { 33cb93a386Sopenharmony_ci SkASSERT(type.isVector()); 34cb93a386Sopenharmony_ci SkASSERT(type.componentType() == scalar.type()); 35cb93a386Sopenharmony_ci } 36cb93a386Sopenharmony_ci 37cb93a386Sopenharmony_ci // The input argument must be scalar. A "splat" to a scalar type will be optimized into a no-op. 38cb93a386Sopenharmony_ci static std::unique_ptr<Expression> Make(const Context& context, 39cb93a386Sopenharmony_ci int line, 40cb93a386Sopenharmony_ci const Type& type, 41cb93a386Sopenharmony_ci std::unique_ptr<Expression> arg); 42cb93a386Sopenharmony_ci 43cb93a386Sopenharmony_ci std::unique_ptr<Expression> clone() const override { 44cb93a386Sopenharmony_ci return std::make_unique<ConstructorSplat>(fLine, this->type(), argument()->clone()); 45cb93a386Sopenharmony_ci } 46cb93a386Sopenharmony_ci 47cb93a386Sopenharmony_ci bool supportsConstantValues() const override { 48cb93a386Sopenharmony_ci return true; 49cb93a386Sopenharmony_ci } 50cb93a386Sopenharmony_ci 51cb93a386Sopenharmony_ci skstd::optional<double> getConstantValue(int n) const override { 52cb93a386Sopenharmony_ci SkASSERT(n >= 0 && n < this->type().columns()); 53cb93a386Sopenharmony_ci return this->argument()->getConstantValue(0); 54cb93a386Sopenharmony_ci } 55cb93a386Sopenharmony_ci 56cb93a386Sopenharmony_ciprivate: 57cb93a386Sopenharmony_ci using INHERITED = SingleArgumentConstructor; 58cb93a386Sopenharmony_ci}; 59cb93a386Sopenharmony_ci 60cb93a386Sopenharmony_ci} // namespace SkSL 61cb93a386Sopenharmony_ci 62cb93a386Sopenharmony_ci#endif 63