1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2016 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #ifndef SKSL_CODEGENERATOR 9*c8dee2aaSAndroid Build Coastguard Worker #define SKSL_CODEGENERATOR 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLContext.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLOutputStream.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/ir/SkSLProgram.h" 14*c8dee2aaSAndroid Build Coastguard Worker 15*c8dee2aaSAndroid Build Coastguard Worker namespace SkSL { 16*c8dee2aaSAndroid Build Coastguard Worker 17*c8dee2aaSAndroid Build Coastguard Worker struct ShaderCaps; 18*c8dee2aaSAndroid Build Coastguard Worker 19*c8dee2aaSAndroid Build Coastguard Worker /** 20*c8dee2aaSAndroid Build Coastguard Worker * Abstract superclass of all code generators, which take a Program as input and produce code as 21*c8dee2aaSAndroid Build Coastguard Worker * output. 22*c8dee2aaSAndroid Build Coastguard Worker */ 23*c8dee2aaSAndroid Build Coastguard Worker class CodeGenerator { 24*c8dee2aaSAndroid Build Coastguard Worker public: CodeGenerator(const Context * context,const ShaderCaps * caps,const Program * program,OutputStream * stream)25*c8dee2aaSAndroid Build Coastguard Worker CodeGenerator(const Context* context, 26*c8dee2aaSAndroid Build Coastguard Worker const ShaderCaps* caps, 27*c8dee2aaSAndroid Build Coastguard Worker const Program* program, 28*c8dee2aaSAndroid Build Coastguard Worker OutputStream* stream) 29*c8dee2aaSAndroid Build Coastguard Worker : fProgram(*program) 30*c8dee2aaSAndroid Build Coastguard Worker , fContext(fProgram.fContext->fTypes, *fProgram.fContext->fErrors) 31*c8dee2aaSAndroid Build Coastguard Worker , fCaps(*caps) 32*c8dee2aaSAndroid Build Coastguard Worker , fOut(stream) { 33*c8dee2aaSAndroid Build Coastguard Worker fContext.fConfig = fProgram.fConfig.get(); 34*c8dee2aaSAndroid Build Coastguard Worker fContext.fModule = fProgram.fContext->fModule; 35*c8dee2aaSAndroid Build Coastguard Worker fContext.fSymbolTable = fProgram.fSymbols.get(); 36*c8dee2aaSAndroid Build Coastguard Worker } 37*c8dee2aaSAndroid Build Coastguard Worker 38*c8dee2aaSAndroid Build Coastguard Worker virtual ~CodeGenerator() = default; 39*c8dee2aaSAndroid Build Coastguard Worker 40*c8dee2aaSAndroid Build Coastguard Worker virtual bool generateCode() = 0; 41*c8dee2aaSAndroid Build Coastguard Worker 42*c8dee2aaSAndroid Build Coastguard Worker // Intended for use by AutoOutputStream. outputStream()43*c8dee2aaSAndroid Build Coastguard Worker OutputStream* outputStream() { return fOut; } setOutputStream(OutputStream * output)44*c8dee2aaSAndroid Build Coastguard Worker void setOutputStream(OutputStream* output) { fOut = output; } 45*c8dee2aaSAndroid Build Coastguard Worker 46*c8dee2aaSAndroid Build Coastguard Worker protected: 47*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_USE_LEGACY_MIPMAP_LOD_BIAS) 48*c8dee2aaSAndroid Build Coastguard Worker static constexpr float kSharpenTexturesBias = -.5f; 49*c8dee2aaSAndroid Build Coastguard Worker #else 50*c8dee2aaSAndroid Build Coastguard Worker // For SkMipmapMode::kLinear we want a bias such that when the unbiased LOD value is 51*c8dee2aaSAndroid Build Coastguard Worker // midway between levels we select just the larger level, i.e. a bias of -.5. However, using 52*c8dee2aaSAndroid Build Coastguard Worker // this bias with kNearest mode with a draw that is a perfect power of two downscale puts us 53*c8dee2aaSAndroid Build Coastguard Worker // right on the rounding edge where it could go up or down depending on the particular GPU. 54*c8dee2aaSAndroid Build Coastguard Worker // Experimentally we found that at -.49 most iOS devices (iPhone 7, 8, and iPad Pro 55*c8dee2aaSAndroid Build Coastguard Worker // [PowerVRGT7800 version]) all round to the level twice as big as the device space footprint 56*c8dee2aaSAndroid Build Coastguard Worker // for some such draws in our unit tests on GLES. However, the iPhone 11 still fails and so 57*c8dee2aaSAndroid Build Coastguard Worker // we are using -.475. They do not at -.48. All other GPUs passed tests with -.499. Though, at 58*c8dee2aaSAndroid Build Coastguard Worker // this time the bias is not implemented in the MSL codegen and so iOS/Metal was not tested. 59*c8dee2aaSAndroid Build Coastguard Worker static constexpr float kSharpenTexturesBias = -.475f; 60*c8dee2aaSAndroid Build Coastguard Worker #endif 61*c8dee2aaSAndroid Build Coastguard Worker 62*c8dee2aaSAndroid Build Coastguard Worker const Program& fProgram; 63*c8dee2aaSAndroid Build Coastguard Worker Context fContext; 64*c8dee2aaSAndroid Build Coastguard Worker const ShaderCaps& fCaps; 65*c8dee2aaSAndroid Build Coastguard Worker OutputStream* fOut; 66*c8dee2aaSAndroid Build Coastguard Worker }; 67*c8dee2aaSAndroid Build Coastguard Worker 68*c8dee2aaSAndroid Build Coastguard Worker class AutoOutputStream { 69*c8dee2aaSAndroid Build Coastguard Worker public: 70*c8dee2aaSAndroid Build Coastguard Worker // Maintains the current indentation level while writing to the new output stream. AutoOutputStream(CodeGenerator * codeGen,OutputStream * newOutput)71*c8dee2aaSAndroid Build Coastguard Worker AutoOutputStream(CodeGenerator* codeGen, OutputStream* newOutput) 72*c8dee2aaSAndroid Build Coastguard Worker : fCodeGen(codeGen) 73*c8dee2aaSAndroid Build Coastguard Worker , fOldOutput(codeGen->outputStream()) { 74*c8dee2aaSAndroid Build Coastguard Worker fCodeGen->setOutputStream(newOutput); 75*c8dee2aaSAndroid Build Coastguard Worker } 76*c8dee2aaSAndroid Build Coastguard Worker // Resets the indentation when entering the scope, and restores it when leaving. AutoOutputStream(CodeGenerator * codeGen,OutputStream * newOutput,int * indentationPtr)77*c8dee2aaSAndroid Build Coastguard Worker AutoOutputStream(CodeGenerator* codeGen, OutputStream* newOutput, int *indentationPtr) 78*c8dee2aaSAndroid Build Coastguard Worker : fCodeGen(codeGen) 79*c8dee2aaSAndroid Build Coastguard Worker , fOldOutput(codeGen->outputStream()) 80*c8dee2aaSAndroid Build Coastguard Worker , fIndentationPtr(indentationPtr) 81*c8dee2aaSAndroid Build Coastguard Worker , fOldIndentation(indentationPtr ? *indentationPtr : 0) { 82*c8dee2aaSAndroid Build Coastguard Worker fCodeGen->setOutputStream(newOutput); 83*c8dee2aaSAndroid Build Coastguard Worker *fIndentationPtr = 0; 84*c8dee2aaSAndroid Build Coastguard Worker } ~AutoOutputStream()85*c8dee2aaSAndroid Build Coastguard Worker ~AutoOutputStream() { 86*c8dee2aaSAndroid Build Coastguard Worker fCodeGen->setOutputStream(fOldOutput); 87*c8dee2aaSAndroid Build Coastguard Worker if (fIndentationPtr) { 88*c8dee2aaSAndroid Build Coastguard Worker *fIndentationPtr = fOldIndentation; 89*c8dee2aaSAndroid Build Coastguard Worker } 90*c8dee2aaSAndroid Build Coastguard Worker } 91*c8dee2aaSAndroid Build Coastguard Worker 92*c8dee2aaSAndroid Build Coastguard Worker private: 93*c8dee2aaSAndroid Build Coastguard Worker CodeGenerator* fCodeGen = nullptr; 94*c8dee2aaSAndroid Build Coastguard Worker OutputStream* fOldOutput = nullptr; 95*c8dee2aaSAndroid Build Coastguard Worker int *fIndentationPtr = nullptr; 96*c8dee2aaSAndroid Build Coastguard Worker int fOldIndentation = 0; 97*c8dee2aaSAndroid Build Coastguard Worker }; 98*c8dee2aaSAndroid Build Coastguard Worker 99*c8dee2aaSAndroid Build Coastguard Worker } // namespace SkSL 100*c8dee2aaSAndroid Build Coastguard Worker 101*c8dee2aaSAndroid Build Coastguard Worker #endif 102