#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 <int Precedence, Associativity Assoc> 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 <int Precedence, bool Float, bool Int, bool Bool, class ComputeValueRange, class EvaluateComp> class BinaryVecOp : public BinaryOp<Precedence, ASSOCIATIVITY_LEFT> { 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(DE_FALSE); } }; struct EvaluateMul { template <typename T> 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 <typename T> void operator() (de::Random& rnd, T dstMin, T dstMax, T& aMin, T& aMax, T& bMin, T& bMax) const; }; struct EvaluateAdd { template <typename T> 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 <typename T> void operator() (de::Random& rnd, T dstMin, T dstMax, T& aMin, T& aMax, T& bMin, T& bMax) const; }; struct EvaluateSub { template <typename T> 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 ComputeValueRange, class EvaluateComp> 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 <typename T> void operator() (de::Random& rnd, bool dstMin, bool dstMax, T& aMin, T& aMax, T& bMin, T& bMax) const; }; struct EvaluateLessThan { template <typename T> inline bool operator() (T a, T b) const { return a < b; } }; typedef RelationalOp<ComputeLessThanRange, EvaluateLessThan> 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 <typename T> void operator() (de::Random& rnd, bool dstMin, bool dstMax, T& aMin, T& aMax, T& bMin, T& bMax) const; }; struct EvaluateLessOrEqual { template <typename T> inline bool operator() (T a, T b) const { return a <= b; } }; typedef RelationalOp<ComputeLessOrEqualRange, EvaluateLessOrEqual> 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 <typename T> 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 <typename T> inline bool operator() (T a, T b) const { return a > b; } }; typedef RelationalOp<ComputeGreaterThanRange, EvaluateGreaterThan> 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 <typename T> 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 <typename T> inline bool operator() (T a, T b) const { return a >= b; } }; typedef RelationalOp<ComputeGreaterOrEqualRange, EvaluateGreaterOrEqual> 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 <bool IsEqual> 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<true> { public: EqualOp (GeneratorState& state, ConstValueRangeAccess valueRange); static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange); }; class NotEqualOp : public EqualityComparisonOp<false> { public: NotEqualOp (GeneratorState& state, ConstValueRangeAccess valueRange); static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange); }; } // rsg #endif // _RSGBINARYOPS_HPP