blob: 0177fea968a780d2df242cd9f3f4b63aa010133d [file] [log] [blame]
Qiankun Miao09cfac62016-09-06 17:25:16 +08001//
2// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7#include "compiler/translator/AddAndTrueToLoopCondition.h"
8
9#include "compiler/translator/IntermNode.h"
10
11namespace sh
12{
13
14namespace
15{
16
17// An AST traverser that rewrites for and while loops by replacing "condition" with
18// "condition && true" to work around condition bug on Intel Mac.
19class AddAndTrueToLoopConditionTraverser : public TIntermTraverser
20{
21 public:
22 AddAndTrueToLoopConditionTraverser() : TIntermTraverser(true, false, false) {}
23
24 bool visitLoop(Visit, TIntermLoop *loop) override
25 {
26 // do-while loop doesn't have this bug.
27 if (loop->getType() != ELoopFor && loop->getType() != ELoopWhile)
28 {
29 return true;
30 }
31
32 // For loop may not have a condition.
33 if (loop->getCondition() == nullptr)
34 {
35 return true;
36 }
37
38 // Constant true.
39 TConstantUnion *trueConstant = new TConstantUnion();
40 trueConstant->setBConst(true);
41 TIntermTyped *trueValue = new TIntermConstantUnion(trueConstant, TType(EbtBool));
42
43 // CONDITION && true.
44 TIntermBinary *andOp = new TIntermBinary(EOpLogicalAnd, loop->getCondition(), trueValue);
45 loop->setCondition(andOp);
46
47 return true;
48 }
49};
50
51} // anonymous namespace
52
53void AddAndTrueToLoopCondition(TIntermNode *root)
54{
55 AddAndTrueToLoopConditionTraverser traverser;
56 root->traverse(&traverser);
57}
58
59} // namespace sh