#include "src/sksl/codegen/SkSLMetalCodeGenerator.h"
#include "include/core/SkSpan.h"
#include "include/core/SkTypes.h"
#include "include/private/base/SkTArray.h"
#include "include/private/base/SkTo.h"
#include "src/base/SkEnumBitMask.h"
#include "src/base/SkScopeExit.h"
#include "src/core/SkTHash.h"
#include "src/core/SkTraceEvent.h"
#include "src/sksl/SkSLAnalysis.h"
#include "src/sksl/SkSLBuiltinTypes.h"
#include "src/sksl/SkSLCompiler.h"
#include "src/sksl/SkSLContext.h"
#include "src/sksl/SkSLDefines.h"
#include "src/sksl/SkSLErrorReporter.h"
#include "src/sksl/SkSLIntrinsicList.h"
#include "src/sksl/SkSLMemoryLayout.h"
#include "src/sksl/SkSLOperator.h"
#include "src/sksl/SkSLOutputStream.h"
#include "src/sksl/SkSLPosition.h"
#include "src/sksl/SkSLProgramSettings.h"
#include "src/sksl/SkSLString.h"
#include "src/sksl/SkSLStringStream.h"
#include "src/sksl/SkSLUtil.h"
#include "src/sksl/analysis/SkSLProgramVisitor.h"
#include "src/sksl/codegen/SkSLCodeGenTypes.h"
#include "src/sksl/codegen/SkSLCodeGenerator.h"
#include "src/sksl/ir/SkSLBinaryExpression.h"
#include "src/sksl/ir/SkSLBlock.h"
#include "src/sksl/ir/SkSLConstructor.h"
#include "src/sksl/ir/SkSLConstructorArrayCast.h"
#include "src/sksl/ir/SkSLConstructorCompound.h"
#include "src/sksl/ir/SkSLConstructorMatrixResize.h"
#include "src/sksl/ir/SkSLDoStatement.h"
#include "src/sksl/ir/SkSLExpression.h"
#include "src/sksl/ir/SkSLExpressionStatement.h"
#include "src/sksl/ir/SkSLExtension.h"
#include "src/sksl/ir/SkSLFieldAccess.h"
#include "src/sksl/ir/SkSLForStatement.h"
#include "src/sksl/ir/SkSLFunctionCall.h"
#include "src/sksl/ir/SkSLFunctionDeclaration.h"
#include "src/sksl/ir/SkSLFunctionDefinition.h"
#include "src/sksl/ir/SkSLFunctionPrototype.h"
#include "src/sksl/ir/SkSLIRHelpers.h"
#include "src/sksl/ir/SkSLIRNode.h"
#include "src/sksl/ir/SkSLIfStatement.h"
#include "src/sksl/ir/SkSLIndexExpression.h"
#include "src/sksl/ir/SkSLInterfaceBlock.h"
#include "src/sksl/ir/SkSLLayout.h"
#include "src/sksl/ir/SkSLLiteral.h"
#include "src/sksl/ir/SkSLModifierFlags.h"
#include "src/sksl/ir/SkSLNop.h"
#include "src/sksl/ir/SkSLPostfixExpression.h"
#include "src/sksl/ir/SkSLPrefixExpression.h"
#include "src/sksl/ir/SkSLProgram.h"
#include "src/sksl/ir/SkSLProgramElement.h"
#include "src/sksl/ir/SkSLReturnStatement.h"
#include "src/sksl/ir/SkSLSetting.h"
#include "src/sksl/ir/SkSLStatement.h"
#include "src/sksl/ir/SkSLStructDefinition.h"
#include "src/sksl/ir/SkSLSwitchCase.h"
#include "src/sksl/ir/SkSLSwitchStatement.h"
#include "src/sksl/ir/SkSLSwizzle.h"
#include "src/sksl/ir/SkSLTernaryExpression.h"
#include "src/sksl/ir/SkSLType.h"
#include "src/sksl/ir/SkSLVarDeclarations.h"
#include "src/sksl/ir/SkSLVariable.h"
#include "src/sksl/ir/SkSLVariableReference.h"
#include "src/sksl/spirv.h"
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <initializer_list>
#include <limits>
#include <memory>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
usingnamespaceskia_private;
namespace SkSL {
class MetalCodeGenerator : public CodeGenerator { … };
static const char* operator_name(Operator op) { … }
class MetalCodeGenerator::GlobalStructVisitor { … };
class MetalCodeGenerator::ThreadgroupStructVisitor { … };
void MetalCodeGenerator::write(std::string_view s) { … }
void MetalCodeGenerator::writeLine(std::string_view s) { … }
void MetalCodeGenerator::finishLine() { … }
void MetalCodeGenerator::writeExtension(const Extension& ext) { … }
std::string MetalCodeGenerator::typeName(const Type& raw) { … }
void MetalCodeGenerator::writeStructDefinition(const StructDefinition& s) { … }
void MetalCodeGenerator::writeType(const Type& type) { … }
void MetalCodeGenerator::writeExpression(const Expression& expr, Precedence parentPrecedence) { … }
static bool pass_by_reference(const Type& type, ModifierFlags flags) { … }
static bool needs_address_space(const Type& type, ModifierFlags modifiers) { … }
static bool is_buffer(const InterfaceBlock& block) { … }
static bool is_readonly(const InterfaceBlock& block) { … }
std::string MetalCodeGenerator::getBitcastIntrinsic(const Type& outType) { … }
void MetalCodeGenerator::writeWithIndexSubstitution(const std::function<void()>& fn) { … }
void MetalCodeGenerator::writeFunctionCall(const FunctionCall& c) { … }
static constexpr char kInverse2x2[] = …;
static constexpr char kInverse3x3[] = …;
static constexpr char kInverse4x4[] = …;
std::string MetalCodeGenerator::getInversePolyfill(const ExpressionArray& arguments) { … }
void MetalCodeGenerator::writeMatrixCompMult() { … }
void MetalCodeGenerator::writeOuterProduct() { … }
std::string MetalCodeGenerator::getTempVariable(const Type& type) { … }
void MetalCodeGenerator::writeSimpleIntrinsic(const FunctionCall& c) { … }
void MetalCodeGenerator::writeArgumentList(const ExpressionArray& arguments) { … }
bool MetalCodeGenerator::writeIntrinsicCall(const FunctionCall& c, IntrinsicKind kind) { … }
void MetalCodeGenerator::assembleMatrixFromMatrix(const Type& sourceMatrix, int columns, int rows) { … }
void MetalCodeGenerator::assembleMatrixFromExpressions(const AnyConstructor& ctor,
int columns,
int rows) { … }
std::string MetalCodeGenerator::getMatrixConstructHelper(const AnyConstructor& c) { … }
bool MetalCodeGenerator::matrixConstructHelperIsNeeded(const ConstructorCompound& c) { … }
void MetalCodeGenerator::writeConstructorMatrixResize(const ConstructorMatrixResize& c,
Precedence parentPrecedence) { … }
void MetalCodeGenerator::writeConstructorCompound(const ConstructorCompound& c,
Precedence parentPrecedence) { … }
void MetalCodeGenerator::writeConstructorArrayCast(const ConstructorArrayCast& c,
Precedence parentPrecedence) { … }
std::string MetalCodeGenerator::getVectorFromMat2x2ConstructorHelper(const Type& matrixType) { … }
void MetalCodeGenerator::writeConstructorCompoundVector(const ConstructorCompound& c,
Precedence parentPrecedence) { … }
void MetalCodeGenerator::writeConstructorCompoundMatrix(const ConstructorCompound& c,
Precedence parentPrecedence) { … }
void MetalCodeGenerator::writeAnyConstructor(const AnyConstructor& c,
const char* leftBracket,
const char* rightBracket,
Precedence parentPrecedence) { … }
void MetalCodeGenerator::writeCastConstructor(const AnyConstructor& c,
const char* leftBracket,
const char* rightBracket,
Precedence parentPrecedence) { … }
void MetalCodeGenerator::writeFragCoord() { … }
static bool is_compute_builtin(const Variable& var) { … }
static bool is_input(const Variable& var) { … }
static bool is_output(const Variable& var) { … }
static bool is_uniforms(const Variable& var) { … }
static bool is_threadgroup(const Variable& var) { … }
static bool is_in_globals(const Variable& var) { … }
void MetalCodeGenerator::writeVariableReference(const VariableReference& ref) { … }
void MetalCodeGenerator::writeIndexInnerExpression(const Expression& expr) { … }
void MetalCodeGenerator::writeIndexExpression(const IndexExpression& expr) { … }
void MetalCodeGenerator::writeFieldAccess(const FieldAccess& f) { … }
void MetalCodeGenerator::writeSwizzle(const Swizzle& swizzle) { … }
void MetalCodeGenerator::writeMatrixTimesEqualHelper(const Type& left, const Type& right,
const Type& result) { … }
void MetalCodeGenerator::writeMatrixEqualityHelpers(const Type& left, const Type& right) { … }
void MetalCodeGenerator::writeMatrixDivisionHelpers(const Type& type) { … }
void MetalCodeGenerator::writeArrayEqualityHelpers(const Type& type) { … }
void MetalCodeGenerator::writeStructEqualityHelpers(const Type& type) { … }
void MetalCodeGenerator::writeEqualityHelpers(const Type& leftType, const Type& rightType) { … }
std::string MetalCodeGenerator::splatMatrixOf1(const Type& type) { … }
void MetalCodeGenerator::writeNumberAsMatrix(const Expression& expr, const Type& matrixType) { … }
void MetalCodeGenerator::writeBinaryExpressionElement(const Expression& expr,
Operator op,
const Expression& other,
Precedence precedence) { … }
void MetalCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
Precedence parentPrecedence) { … }
void MetalCodeGenerator::writeTernaryExpression(const TernaryExpression& t,
Precedence parentPrecedence) { … }
void MetalCodeGenerator::writePrefixExpression(const PrefixExpression& p,
Precedence parentPrecedence) { … }
void MetalCodeGenerator::writePostfixExpression(const PostfixExpression& p,
Precedence parentPrecedence) { … }
void MetalCodeGenerator::writeLiteral(const Literal& l) { … }
void MetalCodeGenerator::writeFunctionRequirementArgs(const FunctionDeclaration& f,
const char*& separator) { … }
void MetalCodeGenerator::writeFunctionRequirementParams(const FunctionDeclaration& f,
const char*& separator) { … }
int MetalCodeGenerator::getUniformBinding(const Layout& layout) { … }
int MetalCodeGenerator::getUniformSet(const Layout& layout) { … }
bool MetalCodeGenerator::writeFunctionDeclaration(const FunctionDeclaration& f) { … }
void MetalCodeGenerator::writeFunctionPrototype(const FunctionPrototype& f) { … }
static bool is_block_ending_with_return(const Statement* stmt) { … }
void MetalCodeGenerator::writeComputeMainInputs() { … }
void MetalCodeGenerator::writeFunction(const FunctionDefinition& f) { … }
void MetalCodeGenerator::writeModifiers(ModifierFlags flags) { … }
void MetalCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) { … }
void MetalCodeGenerator::writeFields(SkSpan<const Field> fields, Position parentPos) { … }
void MetalCodeGenerator::writeVarInitializer(const Variable& var, const Expression& value) { … }
void MetalCodeGenerator::writeName(std::string_view name) { … }
void MetalCodeGenerator::writeVarDeclaration(const VarDeclaration& varDecl) { … }
void MetalCodeGenerator::writeStatement(const Statement& s) { … }
void MetalCodeGenerator::writeBlock(const Block& b) { … }
void MetalCodeGenerator::writeIfStatement(const IfStatement& stmt) { … }
void MetalCodeGenerator::writeForStatement(const ForStatement& f) { … }
void MetalCodeGenerator::writeDoStatement(const DoStatement& d) { … }
void MetalCodeGenerator::writeExpressionStatement(const ExpressionStatement& s) { … }
void MetalCodeGenerator::writeSwitchStatement(const SwitchStatement& s) { … }
void MetalCodeGenerator::writeReturnStatementFromMain() { … }
void MetalCodeGenerator::writeReturnStatement(const ReturnStatement& r) { … }
void MetalCodeGenerator::writeHeader() { … }
void MetalCodeGenerator::writeSampler2DPolyfill() { … }
void MetalCodeGenerator::writeUniformStruct() { … }
void MetalCodeGenerator::writeInterpolatedAttributes(const Variable& var) { … }
void MetalCodeGenerator::writeInputStruct() { … }
void MetalCodeGenerator::writeOutputStruct() { … }
void MetalCodeGenerator::writeInterfaceBlocks() { … }
void MetalCodeGenerator::writeStructDefinitions() { … }
void MetalCodeGenerator::writeConstantVariables() { … }
void MetalCodeGenerator::visitGlobalStruct(GlobalStructVisitor* visitor) { … }
void MetalCodeGenerator::writeGlobalStruct() { … }
void MetalCodeGenerator::writeGlobalInit() { … }
void MetalCodeGenerator::visitThreadgroupStruct(ThreadgroupStructVisitor* visitor) { … }
void MetalCodeGenerator::writeThreadgroupStruct() { … }
void MetalCodeGenerator::writeThreadgroupInit() { … }
void MetalCodeGenerator::writeProgramElement(const ProgramElement& e) { … }
MetalCodeGenerator::Requirements MetalCodeGenerator::requirements(const Statement* s) { … }
MetalCodeGenerator::Requirements MetalCodeGenerator::requirements(const FunctionDeclaration& f) { … }
bool MetalCodeGenerator::generateCode() { … }
bool ToMetal(Program& program, const ShaderCaps* caps, OutputStream& out, PrettyPrint pp) { … }
bool ToMetal(Program& program, const ShaderCaps* caps, OutputStream& out) { … }
bool ToMetal(Program& program, const ShaderCaps* caps, std::string* out) { … }
}