/*------------------------------------------------------------------------- * drawElements Quality Program Random Shader Generator * ---------------------------------------------------- * * Copyright 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *//*! * \file * \brief Shader Class. *//*--------------------------------------------------------------------*/ #include "rsgShader.hpp" using std::vector; namespace rsg { namespace { template <typename T> void deleteVectorElements (std::vector<T*>& vec) { for (typename std::vector<T*>::iterator i = vec.begin(); i != vec.end(); i++) delete *i; vec.clear(); } } // anonymous Function::Function (void) { } Function::Function (const char* name) : m_name(name) { } Function::~Function (void) { deleteVectorElements(m_parameters); } ShaderInput::ShaderInput (const Variable* variable, ConstValueRangeAccess valueRange) : m_variable (variable) , m_min (variable->getType().getScalarSize()) , m_max (variable->getType().getScalarSize()) { ValueAccess(variable->getType(), &m_min[0]) = valueRange.getMin().value(); ValueAccess(variable->getType(), &m_max[0]) = valueRange.getMax().value(); } Shader::Shader (Type type) : m_type (type) , m_mainFunction ("main") { } Shader::~Shader (void) { deleteVectorElements(m_functions); deleteVectorElements(m_globalStatements); deleteVectorElements(m_inputs); deleteVectorElements(m_uniforms); } void Shader::getOutputs (vector<const Variable*>& outputs) const { outputs.clear(); const vector<Variable*>& globalVars = m_globalScope.getDeclaredVariables(); for (vector<Variable*>::const_iterator i = globalVars.begin(); i != globalVars.end(); i++) { const Variable* var = *i; if (var->getStorage() == Variable::STORAGE_SHADER_OUT) outputs.push_back(var); } } void Shader::tokenize (GeneratorState& state, TokenStream& str) const { // Add default precision for float in fragment shaders \todo [pyry] Proper precision handling if (state.getShader().getType() == Shader::TYPE_FRAGMENT) str << Token::PRECISION << Token::MEDIUM_PRECISION << Token::FLOAT << Token::SEMICOLON << Token::NEWLINE; // Tokenize global declaration statements for (int ndx = (int)m_globalStatements.size()-1; ndx >= 0; ndx--) m_globalStatements[ndx]->tokenize(state, str); // Tokenize all functions for (int ndx = (int)m_functions.size()-1; ndx >= 0; ndx--) { str << Token::NEWLINE; m_functions[ndx]->tokenize(state, str); } // Tokenize main str << Token::NEWLINE; m_mainFunction.tokenize(state, str); } void Shader::execute (ExecutionContext& execCtx) const { // Execute global statements (declarations) for (vector<Statement*>::const_reverse_iterator i = m_globalStatements.rbegin(); i != m_globalStatements.rend(); i++) (*i)->execute(execCtx); // \todo [2011-03-08 pyry] Proper function calls m_mainFunction.getBody().execute(execCtx); } void Function::tokenize (GeneratorState& state, TokenStream& str) const { // Return type m_returnType.tokenizeShortType(str); // Function name DE_ASSERT(m_name != ""); str << Token(m_name.c_str()); // Parameters str << Token::LEFT_PAREN; for (vector<Variable*>::const_iterator i = m_parameters.begin(); i != m_parameters.end(); i++) { if (i != m_parameters.begin()) str << Token::COMMA; (*i)->tokenizeDeclaration(state, str); } str << Token::RIGHT_PAREN << Token::NEWLINE; // Tokenize body m_functionBlock.tokenize(state, str); } } // rsg