Increase GLSL version to 1.20 if the shader contains any matrix constructor
calls taking a matrix as argument; these were reserved in GLSL 1.10. This
makes http://sio29.sakura.ne.jp/tmp/webgl/index_eruru.html load correctly
once https://bugs.webkit.org/show_bug.cgi?id=52390 is fixed.

BUG=103
TEST=none

Review URL: http://codereview.appspot.com/4034041

git-svn-id: https://angleproject.googlecode.com/svn/trunk@534 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/compiler/VersionGLSL.cpp b/src/compiler/VersionGLSL.cpp
index 3f87820..26cee05 100644
--- a/src/compiler/VersionGLSL.cpp
+++ b/src/compiler/VersionGLSL.cpp
@@ -9,13 +9,17 @@
 static const int GLSL_VERSION_110 = 110;
 static const int GLSL_VERSION_120 = 120;
 
-// We need to scan for two things:
+// We need to scan for three things:
 // 1. "invariant" keyword: This can occur in both - vertex and fragment shaders
 //    but only at the global scope.
 // 2. "gl_PointCoord" built-in variable: This can only occur in fragment shader
 //    but inside any scope.
-// So we need to scan the entire fragment shader but only the global scope
-// of vertex shader.
+// 3. Call to a matrix constructor with another matrix as argument.
+//    (These constructors were reserved in GLSL version 1.10.)
+//
+// If it weren't for (3) then we would only need to scan the global
+// scope of the vertex shader. However, we need to scan the entire
+// shader in both cases.
 //
 // TODO(alokp): The following two cases of invariant decalaration get lost
 // during parsing - they do not get carried over to the intermediate tree.
@@ -34,40 +38,32 @@
 
 void TVersionGLSL::visitSymbol(TIntermSymbol* node)
 {
-    ASSERT(mShaderType == SH_FRAGMENT_SHADER);
-
     if (node->getSymbol() == "gl_PointCoord")
         updateVersion(GLSL_VERSION_120);
 }
 
 void TVersionGLSL::visitConstantUnion(TIntermConstantUnion*)
 {
-    ASSERT(mShaderType == SH_FRAGMENT_SHADER);
 }
 
 bool TVersionGLSL::visitBinary(Visit, TIntermBinary*)
 {
-    ASSERT(mShaderType == SH_FRAGMENT_SHADER);
     return true;
 }
 
 bool TVersionGLSL::visitUnary(Visit, TIntermUnary*)
 {
-    ASSERT(mShaderType == SH_FRAGMENT_SHADER);
     return true;
 }
 
 bool TVersionGLSL::visitSelection(Visit, TIntermSelection*)
 {
-    ASSERT(mShaderType == SH_FRAGMENT_SHADER);
     return true;
 }
 
 bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate* node)
 {
-    // We need to scan the entire fragment shader but only the global scope
-    // of vertex shader.
-    bool visitChildren = mShaderType == SH_FRAGMENT_SHADER ? true : false;
+    bool visitChildren = true;
 
     switch (node->getOp()) {
       case EOpSequence:
@@ -83,6 +79,19 @@
         }
         break;
       }
+      case EOpConstructMat2:
+      case EOpConstructMat3:
+      case EOpConstructMat4: {
+        const TIntermSequence& sequence = node->getSequence();
+        if (sequence.size() == 1) {
+          TIntermTyped* typed = sequence.front()->getAsTyped();
+          if (typed && typed->isMatrix()) {
+            updateVersion(GLSL_VERSION_120);
+          }
+        }
+        break;
+      }
+
       default: break;
     }
 
@@ -91,13 +100,11 @@
 
 bool TVersionGLSL::visitLoop(Visit, TIntermLoop*)
 {
-    ASSERT(mShaderType == SH_FRAGMENT_SHADER);
     return true;
 }
 
 bool TVersionGLSL::visitBranch(Visit, TIntermBranch*)
 {
-    ASSERT(mShaderType == SH_FRAGMENT_SHADER);
     return true;
 }