/*------------------------------------------------------------------------- * 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 Variable Type class. *//*--------------------------------------------------------------------*/ #include "rsgVariableType.hpp" #include "rsgToken.hpp" using std::vector; namespace rsg { VariableType& VariableType::operator= (const VariableType& other) { if (this == &other) return *this; delete m_elementType; m_elementType = DE_NULL; m_baseType = other.m_baseType; m_precision = other.m_precision; m_typeName = other.m_typeName; m_numElements = other.m_numElements; m_members = other.m_members; m_elementType = DE_NULL; if (other.m_elementType) m_elementType = new VariableType(*other.m_elementType); return *this; } VariableType::VariableType (const VariableType& other) : m_elementType(DE_NULL) { *this = other; } bool VariableType::operator!= (const VariableType& other) const { if (m_baseType != other.m_baseType) return true; if (m_precision != other.m_precision) return true; if (m_numElements != other.m_numElements) return true; if (!!m_elementType != !!other.m_elementType) return true; if (m_elementType && *m_elementType != *other.m_elementType) return true; if (m_members != other.m_members) return true; return false; } bool VariableType::operator== (const VariableType& other) const { return !(*this != other); } int VariableType::getScalarSize (void) const { switch (m_baseType) { case TYPE_VOID: case TYPE_FLOAT: case TYPE_INT: case TYPE_BOOL: case TYPE_SAMPLER_2D: case TYPE_SAMPLER_CUBE: return m_numElements; case TYPE_STRUCT: { int sum = 0; for (vector::const_iterator i = m_members.begin(); i != m_members.end(); i++) sum += i->getType().getScalarSize(); return sum; } case TYPE_ARRAY: { DE_ASSERT(m_elementType); return m_elementType->getScalarSize() * m_numElements; } default: DE_ASSERT(false); return 0; } } int VariableType::getMemberScalarOffset (int memberNdx) const { DE_ASSERT(isStruct()); int curOffset = 0; for (vector::const_iterator i = m_members.begin(); i != m_members.begin() + memberNdx; i++) curOffset += i->getType().getScalarSize(); return curOffset; } int VariableType::getElementScalarOffset (int elementNdx) const { DE_ASSERT(isArray()); return elementNdx * getElementType().getScalarSize(); } const VariableType& VariableType::getScalarType (Type baseType) { switch (baseType) { case TYPE_FLOAT: { static const VariableType s_floatTypes[] = { VariableType(TYPE_FLOAT, 1) // \todo [pyry] Extend with different precision variants? }; return s_floatTypes[0]; } case TYPE_INT: { static const VariableType s_intTypes[] = { VariableType(TYPE_INT, 1) }; return s_intTypes[0]; } case TYPE_BOOL: { static const VariableType s_boolTypes[] = { VariableType(TYPE_BOOL, 1) }; return s_boolTypes[0]; } case TYPE_SAMPLER_2D: { static const VariableType sampler2DType = VariableType(TYPE_SAMPLER_2D, 1); return sampler2DType; } case TYPE_SAMPLER_CUBE: { static const VariableType samplerCubeType = VariableType(TYPE_SAMPLER_CUBE, 1); return samplerCubeType; } default: DE_ASSERT(DE_FALSE); throw Exception("VariableType::getScalarType(): unsupported type"); } } const VariableType& VariableType::getElementType (void) const { DE_ASSERT(m_precision == PRECISION_NONE); // \todo [pyry] Precision switch (m_baseType) { case TYPE_FLOAT: case TYPE_INT: case TYPE_BOOL: case TYPE_SAMPLER_2D: case TYPE_SAMPLER_CUBE: return getScalarType(m_baseType); case TYPE_ARRAY: { DE_ASSERT(m_elementType); return *m_elementType; } default: DE_ASSERT(DE_FALSE); throw Exception("VariableType::getElementType(): unsupported type"); } } void VariableType::tokenizeShortType (TokenStream& str) const { switch (m_precision) { case PRECISION_LOW: str << Token::LOW_PRECISION; break; case PRECISION_MEDIUM: str << Token::MEDIUM_PRECISION; break; case PRECISION_HIGH: str << Token::HIGH_PRECISION; break; default: /* nothing */ break; } switch (m_baseType) { case TYPE_VOID: str << Token::VOID; break; case TYPE_FLOAT: switch (m_numElements) { case 1: str << Token::FLOAT; break; case 2: str << Token::VEC2; break; case 3: str << Token::VEC3; break; case 4: str << Token::VEC4; break; default: DE_ASSERT(DE_FALSE); break; } break; case TYPE_INT: switch (m_numElements) { case 1: str << Token::INT; break; case 2: str << Token::IVEC2; break; case 3: str << Token::IVEC3; break; case 4: str << Token::IVEC4; break; default: DE_ASSERT(DE_FALSE); break; } break; case TYPE_BOOL: switch (m_numElements) { case 1: str << Token::BOOL; break; case 2: str << Token::BVEC2; break; case 3: str << Token::BVEC3; break; case 4: str << Token::BVEC4; break; default: DE_ASSERT(DE_FALSE); break; } break; case TYPE_SAMPLER_2D: str << Token::SAMPLER2D; break; case TYPE_SAMPLER_CUBE: str << Token::SAMPLERCUBE; break; case TYPE_STRUCT: DE_ASSERT(m_typeName != ""); str << Token(m_typeName.c_str()); break; case TYPE_ARRAY: DE_ASSERT(m_elementType); m_elementType->tokenizeShortType(str); str << Token::LEFT_BRACKET << Token(m_numElements) << Token::RIGHT_BRACKET; break; default: DE_ASSERT(DE_FALSE); break; } } } // rsg