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