1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2020 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_VMGENERATOR
9cb93a386Sopenharmony_ci#define SKSL_VMGENERATOR
10cb93a386Sopenharmony_ci
11cb93a386Sopenharmony_ci#include "include/core/SkSpan.h"
12cb93a386Sopenharmony_ci#include "include/private/SkSLString.h"
13cb93a386Sopenharmony_ci#include "src/core/SkVM.h"
14cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLType.h"
15cb93a386Sopenharmony_ci
16cb93a386Sopenharmony_ci#include <functional>
17cb93a386Sopenharmony_ci
18cb93a386Sopenharmony_ciclass SkWStream;
19cb93a386Sopenharmony_ci
20cb93a386Sopenharmony_cinamespace SkSL {
21cb93a386Sopenharmony_ci
22cb93a386Sopenharmony_ciclass FunctionDefinition;
23cb93a386Sopenharmony_cistruct Program;
24cb93a386Sopenharmony_ci
25cb93a386Sopenharmony_ciusing SampleShaderFn = std::function<skvm::Color(int, skvm::Coord)>;
26cb93a386Sopenharmony_ciusing SampleColorFilterFn = std::function<skvm::Color(int, skvm::Color)>;
27cb93a386Sopenharmony_ciusing SampleBlenderFn = std::function<skvm::Color(int, skvm::Color, skvm::Color)>;
28cb93a386Sopenharmony_ci
29cb93a386Sopenharmony_cistruct SkVMSlotInfo {
30cb93a386Sopenharmony_ci    /** The full name of this variable (without component): (e.g. `myArray[3].myStruct.myVector`) */
31cb93a386Sopenharmony_ci    std::string             name;
32cb93a386Sopenharmony_ci    /** The dimensions of this variable: 1x1 is a scalar, Nx1 is a vector, NxM is a matrix. */
33cb93a386Sopenharmony_ci    uint8_t                 columns = 1, rows = 1;
34cb93a386Sopenharmony_ci    /** Which component of the variable is this slot? (e.g. `vec4.z` is component 2) */
35cb93a386Sopenharmony_ci    uint8_t                 componentIndex = 0;
36cb93a386Sopenharmony_ci    /** What kind of numbers belong in this slot? */
37cb93a386Sopenharmony_ci    SkSL::Type::NumberKind  numberKind = SkSL::Type::NumberKind::kNonnumeric;
38cb93a386Sopenharmony_ci    /** Where is this variable located in the program? */
39cb93a386Sopenharmony_ci    int                     line;
40cb93a386Sopenharmony_ci};
41cb93a386Sopenharmony_ci
42cb93a386Sopenharmony_cistruct SkVMDebugInfo {
43cb93a386Sopenharmony_ci    void dump(SkWStream* o) const;
44cb93a386Sopenharmony_ci
45cb93a386Sopenharmony_ci    std::vector<SkVMSlotInfo> fSlotInfo;
46cb93a386Sopenharmony_ci};
47cb93a386Sopenharmony_ci
48cb93a386Sopenharmony_ci// Convert 'function' to skvm instructions in 'builder', for use by blends, shaders, & color filters
49cb93a386Sopenharmony_ciskvm::Color ProgramToSkVM(const Program& program,
50cb93a386Sopenharmony_ci                          const FunctionDefinition& function,
51cb93a386Sopenharmony_ci                          skvm::Builder* builder,
52cb93a386Sopenharmony_ci                          SkVMDebugInfo* debugInfo,
53cb93a386Sopenharmony_ci                          SkSpan<skvm::Val> uniforms,
54cb93a386Sopenharmony_ci                          skvm::Coord device,
55cb93a386Sopenharmony_ci                          skvm::Coord local,
56cb93a386Sopenharmony_ci                          skvm::Color inputColor,
57cb93a386Sopenharmony_ci                          skvm::Color destColor,
58cb93a386Sopenharmony_ci                          SampleShaderFn sampleShader,
59cb93a386Sopenharmony_ci                          SampleColorFilterFn sampleColorFilter,
60cb93a386Sopenharmony_ci                          SampleBlenderFn sampleBlender);
61cb93a386Sopenharmony_ci
62cb93a386Sopenharmony_cistruct SkVMSignature {
63cb93a386Sopenharmony_ci    size_t fParameterSlots = 0;
64cb93a386Sopenharmony_ci    size_t fReturnSlots    = 0;
65cb93a386Sopenharmony_ci};
66cb93a386Sopenharmony_ci
67cb93a386Sopenharmony_ci/*
68cb93a386Sopenharmony_ci * Converts 'function' to skvm instructions in 'builder'. Always adds one arg per value in the
69cb93a386Sopenharmony_ci * parameter list, then one per value in the return type. For example:
70cb93a386Sopenharmony_ci *
71cb93a386Sopenharmony_ci *   float2 fn(float2 a, float b) { ... }
72cb93a386Sopenharmony_ci *
73cb93a386Sopenharmony_ci * ... is mapped so that it can be called as:
74cb93a386Sopenharmony_ci *
75cb93a386Sopenharmony_ci *   p.eval(N, &a.x, &a.y, &b, &return.x, &return.y);
76cb93a386Sopenharmony_ci *
77cb93a386Sopenharmony_ci * The number of parameter and return slots (pointers) is placed in 'outSignature', if provided.
78cb93a386Sopenharmony_ci * If the program declares any uniforms, 'uniforms' should contain the IDs of each individual value
79cb93a386Sopenharmony_ci * (eg, one ID per component of a vector).
80cb93a386Sopenharmony_ci */
81cb93a386Sopenharmony_cibool ProgramToSkVM(const Program& program,
82cb93a386Sopenharmony_ci                   const FunctionDefinition& function,
83cb93a386Sopenharmony_ci                   skvm::Builder* b,
84cb93a386Sopenharmony_ci                   SkVMDebugInfo* debugInfo,
85cb93a386Sopenharmony_ci                   SkSpan<skvm::Val> uniforms,
86cb93a386Sopenharmony_ci                   SkVMSignature* outSignature = nullptr);
87cb93a386Sopenharmony_ci
88cb93a386Sopenharmony_ciconst FunctionDefinition* Program_GetFunction(const Program& program, const char* function);
89cb93a386Sopenharmony_ci
90cb93a386Sopenharmony_cistruct UniformInfo {
91cb93a386Sopenharmony_ci    struct Uniform {
92cb93a386Sopenharmony_ci        String fName;
93cb93a386Sopenharmony_ci        Type::NumberKind fKind;
94cb93a386Sopenharmony_ci        int fColumns;
95cb93a386Sopenharmony_ci        int fRows;
96cb93a386Sopenharmony_ci        int fSlot;
97cb93a386Sopenharmony_ci    };
98cb93a386Sopenharmony_ci    std::vector<Uniform> fUniforms;
99cb93a386Sopenharmony_ci    int fUniformSlotCount = 0;
100cb93a386Sopenharmony_ci};
101cb93a386Sopenharmony_ci
102cb93a386Sopenharmony_cistd::unique_ptr<UniformInfo> Program_GetUniformInfo(const Program& program);
103cb93a386Sopenharmony_ci
104cb93a386Sopenharmony_cibool testingOnly_ProgramToSkVMShader(const Program& program,
105cb93a386Sopenharmony_ci                                     skvm::Builder* builder,
106cb93a386Sopenharmony_ci                                     SkVMDebugInfo* debugInfo);
107cb93a386Sopenharmony_ci
108cb93a386Sopenharmony_ci}  // namespace SkSL
109cb93a386Sopenharmony_ci
110cb93a386Sopenharmony_ci#endif
111