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#include "src/sksl/dsl/priv/DSLWriter.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "include/sksl/DSLCore.h" 11cb93a386Sopenharmony_ci#include "include/sksl/DSLStatement.h" 12cb93a386Sopenharmony_ci#include "include/sksl/DSLSymbols.h" 13cb93a386Sopenharmony_ci#include "include/sksl/DSLVar.h" 14cb93a386Sopenharmony_ci#include "src/sksl/SkSLThreadContext.h" 15cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLBlock.h" 16cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLNop.h" 17cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLVarDeclarations.h" 18cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLVariable.h" 19cb93a386Sopenharmony_ci 20cb93a386Sopenharmony_cinamespace SkSL { 21cb93a386Sopenharmony_ci 22cb93a386Sopenharmony_cinamespace dsl { 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_cibool DSLWriter::ManglingEnabled() { 25cb93a386Sopenharmony_ci return ThreadContext::Instance().fSettings.fDSLMangling; 26cb93a386Sopenharmony_ci} 27cb93a386Sopenharmony_ci 28cb93a386Sopenharmony_ciskstd::string_view DSLWriter::Name(skstd::string_view name) { 29cb93a386Sopenharmony_ci if (ManglingEnabled()) { 30cb93a386Sopenharmony_ci const String* s = ThreadContext::SymbolTable()->takeOwnershipOfString( 31cb93a386Sopenharmony_ci ThreadContext::Instance().fMangler.uniqueName(name, 32cb93a386Sopenharmony_ci ThreadContext::SymbolTable().get())); 33cb93a386Sopenharmony_ci return s->c_str(); 34cb93a386Sopenharmony_ci } 35cb93a386Sopenharmony_ci return name; 36cb93a386Sopenharmony_ci} 37cb93a386Sopenharmony_ci 38cb93a386Sopenharmony_ciconst SkSL::Variable* DSLWriter::Var(DSLVarBase& var) { 39cb93a386Sopenharmony_ci // fInitialized is true if we have attempted to create a var, whether or not we actually 40cb93a386Sopenharmony_ci // succeeded. If it's true, we don't want to try again, to avoid reporting the same error 41cb93a386Sopenharmony_ci // multiple times. 42cb93a386Sopenharmony_ci if (!var.fInitialized) { 43cb93a386Sopenharmony_ci // We haven't even attempted to create a var yet, so fVar ought to be null 44cb93a386Sopenharmony_ci SkASSERT(!var.fVar); 45cb93a386Sopenharmony_ci var.fInitialized = true; 46cb93a386Sopenharmony_ci if (var.storage() != SkSL::VariableStorage::kParameter) { 47cb93a386Sopenharmony_ci const SkSL::Type* baseType = &var.fType.skslType(); 48cb93a386Sopenharmony_ci if (baseType->isArray()) { 49cb93a386Sopenharmony_ci baseType = &baseType->componentType(); 50cb93a386Sopenharmony_ci } 51cb93a386Sopenharmony_ci } 52cb93a386Sopenharmony_ci std::unique_ptr<SkSL::Variable> skslvar = SkSL::Variable::Convert(ThreadContext::Context(), 53cb93a386Sopenharmony_ci var.fPosition.line(), var.fModifiers.fModifiers, &var.fType.skslType(), var.fName, 54cb93a386Sopenharmony_ci /*isArray=*/false, /*arraySize=*/nullptr, var.storage()); 55cb93a386Sopenharmony_ci SkSL::Variable* varPtr = skslvar.get(); 56cb93a386Sopenharmony_ci if (var.storage() != SkSL::VariableStorage::kParameter) { 57cb93a386Sopenharmony_ci var.fDeclaration = VarDeclaration::Convert(ThreadContext::Context(), std::move(skslvar), 58cb93a386Sopenharmony_ci var.fInitialValue.releaseIfPossible(), /*addToSymbolTable=*/false); 59cb93a386Sopenharmony_ci if (var.fDeclaration) { 60cb93a386Sopenharmony_ci var.fVar = varPtr; 61cb93a386Sopenharmony_ci var.fInitialized = true; 62cb93a386Sopenharmony_ci } 63cb93a386Sopenharmony_ci } 64cb93a386Sopenharmony_ci ThreadContext::ReportErrors(var.fPosition); 65cb93a386Sopenharmony_ci } 66cb93a386Sopenharmony_ci return var.fVar; 67cb93a386Sopenharmony_ci} 68cb93a386Sopenharmony_ci 69cb93a386Sopenharmony_cistd::unique_ptr<SkSL::Variable> DSLWriter::CreateParameterVar(DSLParameter& var) { 70cb93a386Sopenharmony_ci // This should only be called on undeclared parameter variables, but we allow the creation to go 71cb93a386Sopenharmony_ci // ahead regardless so we don't have to worry about null pointers potentially sneaking in and 72cb93a386Sopenharmony_ci // breaking things. DSLFunction is responsible for reporting errors for invalid parameters. 73cb93a386Sopenharmony_ci return SkSL::Variable::Convert(ThreadContext::Context(), var.fPosition.line(), 74cb93a386Sopenharmony_ci var.fModifiers.fModifiers, &var.fType.skslType(), var.fName, /*isArray=*/false, 75cb93a386Sopenharmony_ci /*arraySize=*/nullptr, var.storage()); 76cb93a386Sopenharmony_ci} 77cb93a386Sopenharmony_ci 78cb93a386Sopenharmony_cistd::unique_ptr<SkSL::Statement> DSLWriter::Declaration(DSLVarBase& var) { 79cb93a386Sopenharmony_ci Var(var); 80cb93a386Sopenharmony_ci if (!var.fDeclaration) { 81cb93a386Sopenharmony_ci // We should have already reported an error before ending up here, just clean up the 82cb93a386Sopenharmony_ci // initial value so it doesn't assert and return a nop. 83cb93a386Sopenharmony_ci var.fInitialValue.releaseIfPossible(); 84cb93a386Sopenharmony_ci return SkSL::Nop::Make(); 85cb93a386Sopenharmony_ci } 86cb93a386Sopenharmony_ci return std::move(var.fDeclaration); 87cb93a386Sopenharmony_ci} 88cb93a386Sopenharmony_ci 89cb93a386Sopenharmony_civoid DSLWriter::MarkDeclared(DSLVarBase& var) { 90cb93a386Sopenharmony_ci SkASSERT(!var.fDeclared); 91cb93a386Sopenharmony_ci var.fDeclared = true; 92cb93a386Sopenharmony_ci} 93cb93a386Sopenharmony_ci 94cb93a386Sopenharmony_cibool DSLWriter::MarkVarsDeclared() { 95cb93a386Sopenharmony_ci return ThreadContext::Instance().fSettings.fDSLMarkVarsDeclared; 96cb93a386Sopenharmony_ci} 97cb93a386Sopenharmony_ci 98cb93a386Sopenharmony_civoid DSLWriter::AddVarDeclaration(DSLStatement& existing, DSLVar& additional) { 99cb93a386Sopenharmony_ci if (existing.fStatement->is<Block>()) { 100cb93a386Sopenharmony_ci SkSL::Block& block = existing.fStatement->as<Block>(); 101cb93a386Sopenharmony_ci SkASSERT(!block.isScope()); 102cb93a386Sopenharmony_ci block.children().push_back(Declare(additional).release()); 103cb93a386Sopenharmony_ci } else if (existing.fStatement->is<VarDeclaration>()) { 104cb93a386Sopenharmony_ci StatementArray stmts; 105cb93a386Sopenharmony_ci stmts.reserve_back(2); 106cb93a386Sopenharmony_ci stmts.push_back(std::move(existing.fStatement)); 107cb93a386Sopenharmony_ci stmts.push_back(Declare(additional).release()); 108cb93a386Sopenharmony_ci existing.fStatement = SkSL::Block::MakeUnscoped(/*line=*/-1, std::move(stmts)); 109cb93a386Sopenharmony_ci } else if (existing.fStatement->isEmpty()) { 110cb93a386Sopenharmony_ci // If the variable declaration generated an error, we can end up with a Nop statement here. 111cb93a386Sopenharmony_ci existing.fStatement = Declare(additional).release(); 112cb93a386Sopenharmony_ci } 113cb93a386Sopenharmony_ci} 114cb93a386Sopenharmony_ci 115cb93a386Sopenharmony_ci#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU 116cb93a386Sopenharmony_ciGrGLSLUniformHandler::UniformHandle DSLWriter::VarUniformHandle(const DSLGlobalVar& var) { 117cb93a386Sopenharmony_ci return GrGLSLUniformHandler::UniformHandle(var.fUniformHandle); 118cb93a386Sopenharmony_ci} 119cb93a386Sopenharmony_ci#endif 120cb93a386Sopenharmony_ci 121cb93a386Sopenharmony_civoid DSLWriter::Reset() { 122cb93a386Sopenharmony_ci dsl::PopSymbolTable(); 123cb93a386Sopenharmony_ci dsl::PushSymbolTable(); 124cb93a386Sopenharmony_ci ThreadContext::ProgramElements().clear(); 125cb93a386Sopenharmony_ci ThreadContext::GetModifiersPool()->clear(); 126cb93a386Sopenharmony_ci} 127cb93a386Sopenharmony_ci 128cb93a386Sopenharmony_ci} // namespace dsl 129cb93a386Sopenharmony_ci 130cb93a386Sopenharmony_ci} // namespace SkSL 131