1/*------------------------------------------------------------------------- 2 * drawElements Quality Program Random Shader Generator 3 * ---------------------------------------------------- 4 * 5 * Copyright 2014 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief Shader Class. 22 *//*--------------------------------------------------------------------*/ 23 24#include "rsgShader.hpp" 25 26using std::vector; 27 28namespace rsg 29{ 30 31namespace 32{ 33 34template <typename T> 35void deleteVectorElements (std::vector<T*>& vec) 36{ 37 for (typename std::vector<T*>::iterator i = vec.begin(); i != vec.end(); i++) 38 delete *i; 39 vec.clear(); 40} 41 42} // anonymous 43 44Function::Function (void) 45{ 46} 47 48Function::Function (const char* name) 49 : m_name(name) 50{ 51} 52 53Function::~Function (void) 54{ 55 deleteVectorElements(m_parameters); 56} 57 58ShaderInput::ShaderInput (const Variable* variable, ConstValueRangeAccess valueRange) 59 : m_variable (variable) 60 , m_min (variable->getType().getScalarSize()) 61 , m_max (variable->getType().getScalarSize()) 62{ 63 ValueAccess(variable->getType(), &m_min[0]) = valueRange.getMin().value(); 64 ValueAccess(variable->getType(), &m_max[0]) = valueRange.getMax().value(); 65} 66 67Shader::Shader (Type type) 68 : m_type (type) 69 , m_mainFunction ("main") 70{ 71} 72 73Shader::~Shader (void) 74{ 75 deleteVectorElements(m_functions); 76 deleteVectorElements(m_globalStatements); 77 deleteVectorElements(m_inputs); 78 deleteVectorElements(m_uniforms); 79} 80 81void Shader::getOutputs (vector<const Variable*>& outputs) const 82{ 83 outputs.clear(); 84 const vector<Variable*>& globalVars = m_globalScope.getDeclaredVariables(); 85 for (vector<Variable*>::const_iterator i = globalVars.begin(); i != globalVars.end(); i++) 86 { 87 const Variable* var = *i; 88 if (var->getStorage() == Variable::STORAGE_SHADER_OUT) 89 outputs.push_back(var); 90 } 91} 92 93void Shader::tokenize (GeneratorState& state, TokenStream& str) const 94{ 95 // Add default precision for float in fragment shaders \todo [pyry] Proper precision handling 96 if (state.getShader().getType() == Shader::TYPE_FRAGMENT) 97 str << Token::PRECISION << Token::MEDIUM_PRECISION << Token::FLOAT << Token::SEMICOLON << Token::NEWLINE; 98 99 // Tokenize global declaration statements 100 for (int ndx = (int)m_globalStatements.size()-1; ndx >= 0; ndx--) 101 m_globalStatements[ndx]->tokenize(state, str); 102 103 // Tokenize all functions 104 for (int ndx = (int)m_functions.size()-1; ndx >= 0; ndx--) 105 { 106 str << Token::NEWLINE; 107 m_functions[ndx]->tokenize(state, str); 108 } 109 110 // Tokenize main 111 str << Token::NEWLINE; 112 m_mainFunction.tokenize(state, str); 113} 114 115void Shader::execute (ExecutionContext& execCtx) const 116{ 117 // Execute global statements (declarations) 118 for (vector<Statement*>::const_reverse_iterator i = m_globalStatements.rbegin(); i != m_globalStatements.rend(); i++) 119 (*i)->execute(execCtx); 120 121 // \todo [2011-03-08 pyry] Proper function calls 122 m_mainFunction.getBody().execute(execCtx); 123} 124 125void Function::tokenize (GeneratorState& state, TokenStream& str) const 126{ 127 // Return type 128 m_returnType.tokenizeShortType(str); 129 130 // Function name 131 DE_ASSERT(m_name != ""); 132 str << Token(m_name.c_str()); 133 134 // Parameters 135 str << Token::LEFT_PAREN; 136 137 for (vector<Variable*>::const_iterator i = m_parameters.begin(); i != m_parameters.end(); i++) 138 { 139 if (i != m_parameters.begin()) 140 str << Token::COMMA; 141 (*i)->tokenizeDeclaration(state, str); 142 } 143 144 str << Token::RIGHT_PAREN << Token::NEWLINE; 145 146 // Tokenize body 147 m_functionBlock.tokenize(state, str); 148} 149 150} // rsg 151