#ifndef _RSGBINARYOPS_HPP #define _RSGBINARYOPS_HPP /*------------------------------------------------------------------------- * 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 Binary operators. *//*--------------------------------------------------------------------*/ #include "rsgDefs.hpp" #include "rsgExpression.hpp" namespace rsg { enum Associativity { ASSOCIATIVITY_LEFT = 0, ASSOCIATIVITY_RIGHT, ASSOCIATIVITY_LAST }; template class BinaryOp : public Expression { public: BinaryOp(Token::Type operatorToken); virtual ~BinaryOp(void); Expression *createNextChild(GeneratorState &state); void tokenize(GeneratorState &state, TokenStream &str) const; void evaluate(ExecutionContext &execCtx); ExecConstValueAccess getValue(void) const { return m_value.getValue(m_type); } virtual void evaluate(ExecValueAccess dst, ExecConstValueAccess a, ExecConstValueAccess b) = DE_NULL; protected: static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); Token::Type m_operator; VariableType m_type; ExecValueStorage m_value; ValueRange m_leftValueRange; ValueRange m_rightValueRange; Expression *m_leftValueExpr; Expression *m_rightValueExpr; }; template class BinaryVecOp : public BinaryOp { public: BinaryVecOp(GeneratorState &state, Token::Type operatorToken, ConstValueRangeAccess valueRange); virtual ~BinaryVecOp(void); void evaluate(ExecValueAccess dst, ExecConstValueAccess a, ExecConstValueAccess b); }; struct ComputeMulRange { void operator()(de::Random &rnd, float dstMin, float dstMax, float &aMin, float &aMax, float &bMin, float &bMax) const; void operator()(de::Random &rnd, int dstMin, int dstMax, int &aMin, int &aMax, int &bMin, int &bMax) const; void operator()(de::Random &, bool, bool, bool &, bool &, bool &, bool &) const { DE_ASSERT(false); } }; struct EvaluateMul { template inline T operator()(T a, T b) const { return a * b; } }; typedef BinaryVecOp<4, true, true, false, ComputeMulRange, EvaluateMul> MulBase; class MulOp : public MulBase { public: MulOp(GeneratorState &state, ConstValueRangeAccess valueRange); virtual ~MulOp(void) { } static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); }; struct ComputeAddRange { template void operator()(de::Random &rnd, T dstMin, T dstMax, T &aMin, T &aMax, T &bMin, T &bMax) const; }; struct EvaluateAdd { template inline T operator()(T a, T b) const { return a + b; } }; typedef BinaryVecOp<5, true, true, false, ComputeAddRange, EvaluateAdd> AddBase; class AddOp : public AddBase { public: AddOp(GeneratorState &state, ConstValueRangeAccess valueRange); virtual ~AddOp(void) { } static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); }; struct ComputeSubRange { template void operator()(de::Random &rnd, T dstMin, T dstMax, T &aMin, T &aMax, T &bMin, T &bMax) const; }; struct EvaluateSub { template inline T operator()(T a, T b) const { return a - b; } }; typedef BinaryVecOp<5, true, true, false, ComputeSubRange, EvaluateSub> SubBase; class SubOp : public SubBase { public: SubOp(GeneratorState &state, ConstValueRangeAccess valueRange); virtual ~SubOp(void) { } static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); }; /* Template for Relational Operators. */ template class RelationalOp : public BinaryOp<7, ASSOCIATIVITY_LEFT> { public: RelationalOp(GeneratorState &state, Token::Type operatorToken, ConstValueRangeAccess valueRange); virtual ~RelationalOp(void); void evaluate(ExecValueAccess dst, ExecConstValueAccess a, ExecConstValueAccess b); static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); }; /* Less Than. */ struct ComputeLessThanRange { template void operator()(de::Random &rnd, bool dstMin, bool dstMax, T &aMin, T &aMax, T &bMin, T &bMax) const; }; struct EvaluateLessThan { template inline bool operator()(T a, T b) const { return a < b; } }; typedef RelationalOp LessThanBase; class LessThanOp : public LessThanBase { public: LessThanOp(GeneratorState &state, ConstValueRangeAccess valueRange); virtual ~LessThanOp(void) { } static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); }; /* Less or Equal. */ struct ComputeLessOrEqualRange { template void operator()(de::Random &rnd, bool dstMin, bool dstMax, T &aMin, T &aMax, T &bMin, T &bMax) const; }; struct EvaluateLessOrEqual { template inline bool operator()(T a, T b) const { return a <= b; } }; typedef RelationalOp LessOrEqualBase; class LessOrEqualOp : public LessOrEqualBase { public: LessOrEqualOp(GeneratorState &state, ConstValueRangeAccess valueRange); virtual ~LessOrEqualOp(void) { } static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); }; /* Greater Than. */ struct ComputeGreaterThanRange { template void operator()(de::Random &rnd, bool dstMin, bool dstMax, T &aMin, T &aMax, T &bMin, T &bMax) const { ComputeLessThanRange()(rnd, dstMin, dstMax, bMin, bMax, aMin, aMax); } }; struct EvaluateGreaterThan { template inline bool operator()(T a, T b) const { return a > b; } }; typedef RelationalOp GreaterThanBase; class GreaterThanOp : public GreaterThanBase { public: GreaterThanOp(GeneratorState &state, ConstValueRangeAccess valueRange); virtual ~GreaterThanOp(void) { } static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); }; /* Greater or Equal. */ struct ComputeGreaterOrEqualRange { template void operator()(de::Random &rnd, bool dstMin, bool dstMax, T &aMin, T &aMax, T &bMin, T &bMax) const { ComputeLessOrEqualRange()(rnd, dstMin, dstMax, bMin, bMax, aMin, aMax); } }; struct EvaluateGreaterOrEqual { template inline bool operator()(T a, T b) const { return a >= b; } }; typedef RelationalOp GreaterOrEqualBase; class GreaterOrEqualOp : public GreaterOrEqualBase { public: GreaterOrEqualOp(GeneratorState &state, ConstValueRangeAccess valueRange); virtual ~GreaterOrEqualOp(void) { } static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); }; /* Equality comparison. */ template class EqualityComparisonOp : public BinaryOp<8, ASSOCIATIVITY_LEFT> { public: EqualityComparisonOp(GeneratorState &state, ConstValueRangeAccess valueRange); virtual ~EqualityComparisonOp(void) { } void evaluate(ExecValueAccess dst, ExecConstValueAccess a, ExecConstValueAccess b); static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); }; // \note Since template implementation is in .cpp we have to reference specialized constructor and static functions from there. class EqualOp : public EqualityComparisonOp { public: EqualOp(GeneratorState &state, ConstValueRangeAccess valueRange); static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); }; class NotEqualOp : public EqualityComparisonOp { public: NotEqualOp(GeneratorState &state, ConstValueRangeAccess valueRange); static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); }; } // namespace rsg #endif // _RSGBINARYOPS_HPP