Merge mozilla-central and mozilla-inbound
authorMarco Bonardo <mbonardo@mozilla.com>
Wed, 31 Aug 2011 10:43:43 +0200
changeset 77567 c7e6f57e173220fddbd6a0542df2f2d03465edae
parent 77515 005bce677a00b9a8e51b5df3f7d1974b261a1f76 (current diff)
parent 77566 86f1809d81d79a98de7ddb7332869997f3bd359d (diff)
child 77568 e043bf9fa4c1e8a2b40dd702f78b745d5c223f3e
child 77576 2ace1d703abeac6d947f85363c96d26ee4b35df7
push id78
push userclegnitto@mozilla.com
push dateFri, 16 Dec 2011 17:32:24 +0000
treeherdermozilla-release@79d24e644fdd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone9.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central and mozilla-inbound
gfx/angle/angle-amap-arev-fix.patch
gfx/angle/angle-r702.patch
gfx/angle/angle-r707.patch
gfx/angle/angle-r712.patch
gfx/angle/angle-win64.patch
gfx/angle/fix-angle-surface-assert.patch
--- a/accessible/src/xul/nsXULTreeGridAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeGridAccessible.cpp
@@ -1165,18 +1165,17 @@ nsXULTreeGridCellAccessible::GetAttribut
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   // "table-cell-index" attribute
   nsAccessible* grandParent = mParent->Parent();
   if (!grandParent)
     return NS_OK;
 
-  nsCOMPtr<nsIAccessibleTable> tableAccessible =
-    do_QueryInterface(static_cast<nsIAccessible*>(grandParent));
+  nsCOMPtr<nsIAccessibleTable> tableAccessible = do_QueryObject(grandParent);
 
   // XXX - temp fix for crash bug 516047
   if (!tableAccessible)
     return NS_ERROR_FAILURE;
     
   PRInt32 colIdx = GetColumnIndex();
 
   PRInt32 cellIdx = -1;
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -793,22 +793,16 @@ pref("browser.sessionstore.restore_on_de
 pref("browser.sessionstore.restore_hidden_tabs", false);
 
 // allow META refresh by default
 pref("accessibility.blockautorefresh", false);
 
 // Whether history is enabled or not.
 pref("places.history.enabled", true);
 
-// The percentage of system memory that the Places database can use.  Out of the
-// allowed cache size it will at most use the size of the database file.
-// Changes to this value are effective after an application restart.
-// Acceptable values are between 0 and 50.
-pref("places.database.cache_to_memory_percentage", 6);
-
 // the (maximum) number of the recent visits to sample
 // when calculating frecency
 pref("places.frecency.numVisits", 10);
 
 // buckets (in days) for frecency calculation
 pref("places.frecency.firstBucketCutoff", 4);
 pref("places.frecency.secondBucketCutoff", 14);
 pref("places.frecency.thirdBucketCutoff", 31);
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -2208,18 +2208,22 @@ var gLastOpenDirectory = {
         if (!this._lastDir.exists())
           this._lastDir = null;
       }
       catch(e) {}
     }
     return this._lastDir;
   },
   set path(val) {
-    if (!val || !val.exists() || !val.isDirectory())
+    try {
+      if (!val || !val.isDirectory())
+        return;
+    } catch(e) {
       return;
+    }
     this._lastDir = val.clone();
 
     // Don't save the last open directory pref inside the Private Browsing mode
     if (!gPrivateBrowsingUI.privateBrowsingEnabled)
       gPrefService.setComplexValue("browser.open.lastDir", Ci.nsILocalFile,
                                    this._lastDir);
   },
   reset: function() {
@@ -2234,18 +2238,21 @@ function BrowserOpenFileWindow()
     const nsIFilePicker = Components.interfaces.nsIFilePicker;
     var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
     fp.init(window, gNavigatorBundle.getString("openFile"), nsIFilePicker.modeOpen);
     fp.appendFilters(nsIFilePicker.filterAll | nsIFilePicker.filterText | nsIFilePicker.filterImages |
                      nsIFilePicker.filterXML | nsIFilePicker.filterHTML);
     fp.displayDirectory = gLastOpenDirectory.path;
 
     if (fp.show() == nsIFilePicker.returnOK) {
-      if (fp.file && fp.file.exists())
-        gLastOpenDirectory.path = fp.file.parent.QueryInterface(Ci.nsILocalFile);
+      try {
+        if (fp.file)
+          gLastOpenDirectory.path = fp.file.parent.QueryInterface(Ci.nsILocalFile);
+      } catch(e) {
+      }
       openTopWin(fp.fileURL.spec);
     }
   } catch (ex) {
   }
 }
 
 function BrowserCloseTabOrWindow() {
 #ifdef XP_MACOSX
--- a/browser/base/content/safeMode.js
+++ b/browser/base/content/safeMode.js
@@ -70,18 +70,21 @@ function restoreDefaultBookmarks() {
 }
 
 function deleteLocalstore() {
   const nsIDirectoryServiceContractID = "@mozilla.org/file/directory_service;1";
   const nsIProperties = Components.interfaces.nsIProperties;
   var directoryService =  Components.classes[nsIDirectoryServiceContractID]
                                     .getService(nsIProperties);
   var localstoreFile = directoryService.get("LStoreS", Components.interfaces.nsIFile);
-  if (localstoreFile.exists())
+  try {
     localstoreFile.remove(false);
+  } catch(e) {
+    Components.utils.reportError(e);
+  }
 }
 
 function disableAddons() {
   AddonManager.getAllAddons(function(aAddons) {
     aAddons.forEach(function(aAddon) {
       if (aAddon.type == "theme") {
         // Setting userDisabled to false on the default theme activates it,
         // disables all other themes and deactivates the applied persona, if
--- a/browser/base/content/tabbrowser.css
+++ b/browser/base/content/tabbrowser.css
@@ -11,22 +11,16 @@
   display: none;
 }
 
 .tabbrowser-tabs[closebuttons="activetab"] > * > * > * > .tab-close-button:not([pinned])[selected="true"],
 .tabbrowser-tabs[closebuttons="alltabs"] > * > * > * > .tab-close-button:not([pinned]) {
   display: -moz-box;
 }
 
-.tab-close-button[selected="true"] {
-  /* Make this button focusable so clicking on it will not focus the tab while
-     it's getting closed */
-  -moz-user-focus: normal;
-}
-
 .tab-label[pinned] {
   width: 0;
   margin-left: 0 !important;
   margin-right: 0 !important;
   padding-left: 0 !important;
   padding-right: 0 !important;
 }
 
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -3997,17 +3997,16 @@
                      class="tab-icon-image"
                      role="presentation"/>
           <xul:label flex="1"
                      xbl:inherits="value=label,crop,accesskey,fadein,pinned,selected"
                      class="tab-text tab-label"
                      role="presentation"/>
           <xul:toolbarbutton anonid="close-button"
                              xbl:inherits="fadein,pinned,selected"
-                             tabindex="-1"
                              clickthrough="never"
                              class="tab-close-button"/>
         </xul:hbox>
       </xul:stack>
     </content>
 
     <implementation>
       <property name="pinned" readonly="true">
@@ -4035,35 +4034,24 @@
       <handler event="mouseout">
         var anonid = event.originalTarget.getAttribute("anonid");
         if (anonid == "close-button")
           this.mOverCloseButton = false;
       </handler>
       <handler event="dragstart" phase="capturing">
         this.style.MozUserFocus = '';
       </handler>
-      <handler event="mousedown" button="0" phase="capturing">
+      <handler event="mousedown">
       <![CDATA[
-        if (this.mOverCloseButton) {
-          event.stopPropagation();
-        }
-        else if (this.selected) {
+        if (this.selected) {
           this.style.MozUserFocus = 'ignore';
           this.clientTop; // just using this to flush style updates
         }
       ]]>
       </handler>
-      <handler event="mousedown" button="1">
-        this.style.MozUserFocus = 'ignore';
-        this.clientTop;
-      </handler>
-      <handler event="mousedown" button="2">
-        this.style.MozUserFocus = 'ignore';
-        this.clientTop;
-      </handler>
       <handler event="mouseup">
         this.style.MozUserFocus = '';
       </handler>
     </handlers>
   </binding>
 
   <binding id="tabbrowser-alltabs-popup"
            extends="chrome://global/content/bindings/popup.xml#popup">
--- a/browser/components/shell/src/nsWindowsShellService.cpp
+++ b/browser/components/shell/src/nsWindowsShellService.cpp
@@ -339,19 +339,21 @@ nsWindowsShellService::IsDefaultBrowserV
   
   HRESULT hr = CoCreateInstance(CLSID_ApplicationAssociationRegistration,
                                 NULL,
                                 CLSCTX_INPROC,
                                 IID_IApplicationAssociationRegistration,
                                 (void**)&pAAR);
 
   if (SUCCEEDED(hr)) {
+    BOOL res;
     hr = pAAR->QueryAppIsDefaultAll(AL_EFFECTIVE,
                                     APP_REG_NAME,
-                                    aIsDefaultBrowser);
+                                    &res);
+    *aIsDefaultBrowser = res;
 
     pAAR->Release();
     return PR_TRUE;
   }
 #endif  
   return PR_FALSE;
 }
 
--- a/browser/themes/winstripe/browser/browser.css
+++ b/browser/themes/winstripe/browser/browser.css
@@ -1863,20 +1863,16 @@ richlistitem[type~="action"][actiontype=
 .tab-close-button:hover:active[selected="true"] {
   -moz-image-region: rect(0, 48px, 16px, 32px);
 }
 
 .tab-close-button[selected="true"] {
   -moz-image-region: rect(0, 16px, 16px, 0);
 }
 
-.tab-close-button:focus {
-  outline: none !important;
-}
-
 /* Tab scrollbox arrow, tabstrip new tab and all-tabs buttons */
 
 @media all and (-moz-touch-enabled) {
   .tabbrowser-arrowscrollbox > .scrollbutton-up,
   .tabbrowser-arrowscrollbox > .scrollbutton-down,
   #TabsToolbar .toolbarbutton-1 {
     min-width: 8.1mozmm;
   }
--- a/build/automation.py.in
+++ b/build/automation.py.in
@@ -331,16 +331,17 @@ class Automation(object):
     self.setupPermissionsDatabase(profileDir,
       {'allowXULXBL':[(l.host, 'noxul' not in l.options) for l in locations]});
 
     part = """\
 user_pref("browser.console.showInPanel", true);
 user_pref("browser.dom.window.dump.enabled", true);
 user_pref("browser.firstrun.show.localepicker", false);
 user_pref("browser.firstrun.show.uidiscovery", false);
+user_pref("browser.ui.layout.tablet", 0); // force tablet UI off
 user_pref("dom.allow_scripts_to_close_windows", true);
 user_pref("dom.disable_open_during_load", false);
 user_pref("dom.max_script_run_time", 0); // no slow script dialogs
 user_pref("dom.max_chrome_script_run_time", 0);
 user_pref("dom.popup_maximum", -1);
 user_pref("dom.send_after_paint_to_content", true);
 user_pref("dom.successive_dialog_time_limit", 0);
 user_pref("signed.applets.codebase_principal_support", true);
--- a/build/mobile/sutagent/android/watcher/AndroidManifest.xml
+++ b/build/mobile/sutagent/android/watcher/AndroidManifest.xml
@@ -1,13 +1,14 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
       package="com.mozilla.watcher"
       android:versionCode="1"
       android:versionName="1.0">
+    <uses-permission android:name="android.permission.WRITE_SETTINGS"></uses-permission>
     <application android:icon="@drawable/icon" android:label="@string/app_name">
         <activity android:name=".WatcherMain"
                   android:label="@string/app_name">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
--- a/build/mobile/sutagent/android/watcher/WatcherService.java
+++ b/build/mobile/sutagent/android/watcher/WatcherService.java
@@ -53,26 +53,30 @@ import java.util.TimerTask;
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.KeyguardManager;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.Service;
 import android.content.ActivityNotFoundException;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.BatteryManager;
+import android.os.Debug;
 import android.os.IBinder;
 import android.os.PowerManager;
 import android.os.RemoteException;
+import android.provider.Settings;
 import android.util.Log;
 import android.view.Gravity;
 import android.widget.Toast;
 
 public class WatcherService extends Service
 {
     String sErrorPrefix = "##Installer Error## ";
     String currentDir = "/";
@@ -129,21 +133,36 @@ public class WatcherService extends Serv
 
         File dir = getFilesDir();
         File iniFile = new File(dir, "watcher.ini");
         String sIniFile = iniFile.getAbsolutePath();
         String sHold = "";
 
         this.sPingTarget = GetIniData("watcher", "PingTarget", sIniFile, "www.mozilla.org");
         sHold = GetIniData("watcher", "delay", sIniFile, "60000");
-           this.lDelay = Long.parseLong(sHold.trim());
+        this.lDelay = Long.parseLong(sHold.trim());
         sHold = GetIniData("watcher", "period", sIniFile,"300000");
-           this.lPeriod = Long.parseLong(sHold.trim());
+        this.lPeriod = Long.parseLong(sHold.trim());
         sHold = GetIniData("watcher", "strikes", sIniFile,"3");
-           this.nMaxStrikes = Integer.parseInt(sHold.trim());
+        this.nMaxStrikes = Integer.parseInt(sHold.trim());
+
+        sHold = GetIniData("watcher", "stayon", sIniFile,"0");
+        int nStayOn = Integer.parseInt(sHold.trim());
+        
+        try {
+            if (nStayOn != 0) {
+                if (!Settings.System.putInt(getContentResolver(), Settings.System.STAY_ON_WHILE_PLUGGED_IN, BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB)) {
+                    doToast("Screen couldn't be set to Always On [stay on while plugged in]");
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            String sExcept = e.getMessage();
+            doToast("Screen couldn't be set to Always On [exception " + sExcept + "]");
+        }
 
         doToast("WatcherService created");
         }
 
     public String GetIniData(String sSection, String sKey, String sFile, String sDefault)
         {
         String sRet = sDefault;
         String sComp = "";
new file mode 100644
--- /dev/null
+++ b/config/makefiles/target_export.mk
@@ -0,0 +1,68 @@
+# -*- makefile -*-
+# vim:set ts=8 sw=8 sts=8 noet:
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (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.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# The Mozilla Foundation
+# Portions created by the Initial Developer are Copyright (C) 2011
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#  Chase Phillips <chase@mozilla.org>
+#  Benjamin Smedberg <benjamin@smedbergs.us>
+#  Jeff Walden <jwalden+code@mit.edu>
+#  Joey Armstrong <joey@mozilla.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+PARALLEL_DIRS_export = $(addsuffix _export,$(PARALLEL_DIRS))
+
+.PHONY: export $(PARALLEL_DIRS_export)
+
+###############
+## TIER targets
+###############
+export_tier_%:
+	@$(ECHO) "$@"
+	@$(MAKE_TIER_SUBMAKEFILES)
+	$(foreach dir,$(tier_$*_dirs),$(call SUBMAKE,export,$(dir)))
+
+#################
+## Common targets
+#################
+ifdef PARALLEL_DIRS
+export:: $(PARALLEL_DIRS_export)
+
+$(PARALLEL_DIRS_export): %_export: %/Makefile
+	+@$(call SUBMAKE,export,$*)
+endif
+
+export:: $(SUBMAKEFILES) $(MAKE_DIRS) $(if $(XPIDLSRCS),$(IDL_DIR))
+	$(LOOP_OVER_DIRS)
+	$(LOOP_OVER_TOOL_DIRS)
new file mode 100644
--- /dev/null
+++ b/config/makefiles/target_libs.mk
@@ -0,0 +1,141 @@
+# -*- makefile -*-
+# vim:set ts=8 sw=8 sts=8 noet:
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (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.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# The Mozilla Foundation
+# Portions created by the Initial Developer are Copyright (C) 2011
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#  Chase Phillips <chase@mozilla.org>
+#  Benjamin Smedberg <benjamin@smedbergs.us>
+#  Jeff Walden <jwalden+code@mit.edu>
+#  Joey Armstrong <joey@mozilla.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+PARALLEL_DIRS_libs = $(addsuffix _libs,$(PARALLEL_DIRS))
+
+.PHONY: libs $(PARALLEL_DIRS_libs)
+
+###############
+## TIER targets
+###############
+libs_tier_%:
+	@$(ECHO) "$@"
+	@$(MAKE_TIER_SUBMAKEFILES)
+	$(foreach dir,$(tier_$*_dirs),$(call SUBMAKE,libs,$(dir)))
+
+#################
+## Common targets
+#################
+ifdef PARALLEL_DIRS
+libs:: $(PARALLEL_DIRS_libs)
+
+$(PARALLEL_DIRS_libs): %_libs: %/Makefile
+	+@$(call SUBMAKE,libs,$*)
+endif
+
+
+####################
+##
+####################
+ifdef EXPORT_LIBRARY
+ifeq ($(EXPORT_LIBRARY),1)
+ifdef IS_COMPONENT
+EXPORT_LIBRARY = $(DEPTH)/staticlib/components
+else
+EXPORT_LIBRARY = $(DEPTH)/staticlib
+endif
+else
+# If EXPORT_LIBRARY has a value, we'll be installing there. We also need to cleanup there
+GARBAGE += $(foreach lib,$(LIBRARY),$(EXPORT_LIBRARY)/$(lib))
+endif
+endif # EXPORT_LIBRARY
+
+libs:: $(SUBMAKEFILES) $(MAKE_DIRS) $(HOST_LIBRARY) $(LIBRARY) $(SHARED_LIBRARY) $(IMPORT_LIBRARY) $(HOST_PROGRAM) $(PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(SIMPLE_PROGRAMS) $(JAVA_LIBRARY)
+ifndef NO_DIST_INSTALL
+ifdef LIBRARY
+ifdef EXPORT_LIBRARY # Stage libs that will be linked into a static build
+	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(EXPORT_LIBRARY)
+endif # EXPORT_LIBRARY
+ifdef DIST_INSTALL
+ifdef IS_COMPONENT
+	$(error Shipping static component libs makes no sense.)
+else
+	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(DIST)/lib
+endif
+endif # DIST_INSTALL
+endif # LIBRARY
+ifdef SHARED_LIBRARY
+ifdef IS_COMPONENT
+	$(INSTALL) $(IFLAGS2) $(SHARED_LIBRARY) $(FINAL_TARGET)/components
+	$(ELF_DYNSTR_GC) $(FINAL_TARGET)/components/$(SHARED_LIBRARY)
+ifndef NO_COMPONENTS_MANIFEST
+	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/chrome.manifest "manifest components/components.manifest"
+	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/components/components.manifest "binary-component $(SHARED_LIBRARY)"
+endif
+else # ! IS_COMPONENT
+ifneq (,$(filter OS2 WINNT,$(OS_ARCH)))
+ifndef NO_INSTALL_IMPORT_LIBRARY
+	$(INSTALL) $(IFLAGS2) $(IMPORT_LIBRARY) $(DIST)/lib
+endif
+else
+	$(INSTALL) $(IFLAGS2) $(SHARED_LIBRARY) $(DIST)/lib
+endif
+	$(INSTALL) $(IFLAGS2) $(SHARED_LIBRARY) $(FINAL_TARGET)
+endif # IS_COMPONENT
+endif # SHARED_LIBRARY
+ifdef PROGRAM
+	$(INSTALL) $(IFLAGS2) $(PROGRAM) $(FINAL_TARGET)
+endif
+ifdef SIMPLE_PROGRAMS
+	$(INSTALL) $(IFLAGS2) $(SIMPLE_PROGRAMS) $(FINAL_TARGET)
+endif
+ifdef HOST_PROGRAM
+	$(INSTALL) $(IFLAGS2) $(HOST_PROGRAM) $(DIST)/host/bin
+endif
+ifdef HOST_SIMPLE_PROGRAMS
+	$(INSTALL) $(IFLAGS2) $(HOST_SIMPLE_PROGRAMS) $(DIST)/host/bin
+endif
+ifdef HOST_LIBRARY
+	$(INSTALL) $(IFLAGS1) $(HOST_LIBRARY) $(DIST)/host/lib
+endif
+ifdef JAVA_LIBRARY
+ifdef IS_COMPONENT
+	$(INSTALL) $(IFLAGS1) $(JAVA_LIBRARY) $(FINAL_TARGET)/components
+else
+	$(INSTALL) $(IFLAGS1) $(JAVA_LIBRARY) $(FINAL_TARGET)
+endif
+endif # JAVA_LIBRARY
+endif # !NO_DIST_INSTALL
+	$(LOOP_OVER_DIRS)
+
+# EOF
new file mode 100644
--- /dev/null
+++ b/config/makefiles/target_tools.mk
@@ -0,0 +1,72 @@
+# -*- makefile -*-
+# vim:set ts=8 sw=8 sts=8 noet:
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (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.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# The Mozilla Foundation
+# Portions created by the Initial Developer are Copyright (C) 2011
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#  Chase Phillips <chase@mozilla.org>
+#  Benjamin Smedberg <benjamin@smedbergs.us>
+#  Jeff Walden <jwalden+code@mit.edu>
+#  Joey Armstrong <joey@mozilla.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+PARALLEL_DIRS_tools = $(addsuffix _tools,$(PARALLEL_DIRS))
+
+.PHONY: tools $(PARALLEL_DIRS_tools)
+
+###############
+## TIER targets
+###############
+tools_tier_%:
+	@$(ECHO) "$@"
+	@$(MAKE_TIER_SUBMAKEFILES)
+	$(foreach dir,$(tier_$*_dirs),$(call SUBMAKE,tools,$(dir)))
+
+#################
+## Common targets
+#################
+ifdef PARALLEL_DIRS
+tools:: $(PARALLEL_DIRS_tools)
+
+$(PARALLEL_DIRS_tools): %_tools: %/Makefile
+	+@$(call SUBMAKE,tools,$*)
+endif
+
+tools:: $(SUBMAKEFILES) $(MAKE_DIRS)
+	$(LOOP_OVER_DIRS)
+ifneq (,$(strip $(TOOL_DIRS)))
+	$(foreach dir,$(TOOL_DIRS),$(call SUBMAKE,libs,$(dir)))
+endif
+
+# EOF
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -1,8 +1,9 @@
+# -*- makefile -*-
 # vim:set ts=8 sw=8 sts=8 noet:
 #
 # ***** BEGIN LICENSE BLOCK *****
 # Version: MPL 1.1/GPL 2.0/LGPL 2.1
 #
 # The contents of this file are subject to the Mozilla Public License Version
 # 1.1 (the "License"); you may not use this file except in compliance with
 # the License. You may obtain a copy of the License at
@@ -19,16 +20,17 @@
 # Netscape Communications Corporation.
 # Portions created by the Initial Developer are Copyright (C) 1998
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
 #  Chase Phillips <chase@mozilla.org>
 #  Benjamin Smedberg <benjamin@smedbergs.us>
 #  Jeff Walden <jwalden+code@mit.edu>
+#  Joey Armstrong <joey@mozilla.com>
 #
 # Alternatively, the contents of this file may be used under the terms of
 # either of the GNU General Public License Version 2 or later (the "GPL"),
 # or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 # in which case the provisions of the GPL or the LGPL are applicable instead
 # of those above. If you wish to allow use of your version of this file only
 # under the terms of either the GPL or the LGPL, and not to allow others to
 # use your version of this file under the terms of the MPL, indicate your
@@ -484,25 +486,16 @@ LOOP_OVER_STATIC_DIRS = \
   $(foreach dir,$(STATIC_DIRS),$(call SUBMAKE,$@,$(dir)))
 endif
 
 ifneq (,$(strip $(TOOL_DIRS)))
 LOOP_OVER_TOOL_DIRS = \
   $(foreach dir,$(TOOL_DIRS),$(call SUBMAKE,$@,$(dir)))
 endif
 
-ifdef PARALLEL_DIRS
-# create a bunch of fake targets for order-only processing
-PARALLEL_DIRS_export = $(addsuffix _export,$(PARALLEL_DIRS))
-PARALLEL_DIRS_libs = $(addsuffix _libs,$(PARALLEL_DIRS))
-PARALLEL_DIRS_tools = $(addsuffix _tools,$(PARALLEL_DIRS))
-
-.PHONY: $(PARALLEL_DIRS_export) $(PARALLEL_DIRS_libs) $(PARALLEL_DIRS_tools)
-endif
-
 #
 # Now we can differentiate between objects used to build a library, and
 # objects used to build an executable in the same directory.
 #
 ifndef PROGOBJS
 PROGOBJS		= $(OBJS)
 endif
 
@@ -731,31 +724,16 @@ ECHO := echo
 QUIET :=
 else
 ECHO := true
 QUIET := -q
 endif
 
 MAKE_TIER_SUBMAKEFILES = +$(if $(tier_$*_dirs),$(MAKE) $(addsuffix /Makefile,$(tier_$*_dirs)))
 
-export_tier_%:
-	@$(ECHO) "$@"
-	@$(MAKE_TIER_SUBMAKEFILES)
-	$(foreach dir,$(tier_$*_dirs),$(call SUBMAKE,export,$(dir)))
-
-libs_tier_%:
-	@$(ECHO) "$@"
-	@$(MAKE_TIER_SUBMAKEFILES)
-	$(foreach dir,$(tier_$*_dirs),$(call SUBMAKE,libs,$(dir)))
-
-tools_tier_%:
-	@$(ECHO) "$@"
-	@$(MAKE_TIER_SUBMAKEFILES)
-	$(foreach dir,$(tier_$*_dirs),$(call SUBMAKE,tools,$(dir)))
-
 $(foreach tier,$(TIERS),tier_$(tier))::
 	@$(ECHO) "$@: $($@_staticdirs) $($@_dirs)"
 	$(foreach dir,$($@_staticdirs),$(call SUBMAKE,,$(dir)))
 	$(MAKE) export_$@
 	$(MAKE) libs_$@
 	$(MAKE) tools_$@
 
 # Do everything from scratch
@@ -769,39 +747,18 @@ depend::
 # Target to only regenerate makefiles
 makefiles: $(SUBMAKEFILES)
 ifneq (,$(DIRS)$(TOOL_DIRS)$(PARALLEL_DIRS))
 	$(LOOP_OVER_PARALLEL_DIRS)
 	$(LOOP_OVER_DIRS)
 	$(LOOP_OVER_TOOL_DIRS)
 endif
 
-ifdef PARALLEL_DIRS
-export:: $(PARALLEL_DIRS_export)
-
-$(PARALLEL_DIRS_export): %_export: %/Makefile
-	+@$(call SUBMAKE,export,$*)
-endif
-
-export:: $(SUBMAKEFILES) $(MAKE_DIRS) $(if $(XPIDLSRCS),$(IDL_DIR))
-	$(LOOP_OVER_DIRS)
-	$(LOOP_OVER_TOOL_DIRS)
-
-ifdef PARALLEL_DIRS
-tools:: $(PARALLEL_DIRS_tools)
-
-$(PARALLEL_DIRS_tools): %_tools: %/Makefile
-	+@$(call SUBMAKE,tools,$*)
-endif
-
-tools:: $(SUBMAKEFILES) $(MAKE_DIRS)
-	$(LOOP_OVER_DIRS)
-ifneq (,$(strip $(TOOL_DIRS)))
-	$(foreach dir,$(TOOL_DIRS),$(call SUBMAKE,libs,$(dir)))
-endif
+include $(topsrcdir)/config/makefiles/target_export.mk
+include $(topsrcdir)/config/makefiles/target_tools.mk
 
 #
 # Rule to create list of libraries for final link
 #
 export::
 ifdef LIBRARY_NAME
 ifdef EXPORT_LIBRARY
 ifdef IS_COMPONENT
@@ -821,96 +778,19 @@ LIBS_DEPS = $(call DO_EXPAND_LIBS,$(filt
 SHARED_LIBRARY_LIBS_DEPS = $(call DO_EXPAND_LIBS,$(SHARED_LIBRARY_LIBS))
 HOST_LIBS_DEPS = $(filter %.$(LIB_SUFFIX),$(HOST_LIBS))
 DSO_LDOPTS_DEPS = $(call DO_EXPAND_LIBS,$(EXTRA_DSO_LIBS) $(filter %.$(LIB_SUFFIX), $(EXTRA_DSO_LDOPTS)))
 
 # Dependencies which, if modified, should cause everything to rebuild
 GLOBAL_DEPS += Makefile Makefile.in $(DEPTH)/config/autoconf.mk $(topsrcdir)/config/config.mk
 
 ##############################################
-ifdef PARALLEL_DIRS
-libs:: $(PARALLEL_DIRS_libs)
-
-$(PARALLEL_DIRS_libs): %_libs: %/Makefile
-	+@$(call SUBMAKE,libs,$*)
-endif
-
-ifdef EXPORT_LIBRARY
-ifeq ($(EXPORT_LIBRARY),1)
-ifdef IS_COMPONENT
-EXPORT_LIBRARY = $(DEPTH)/staticlib/components
-else
-EXPORT_LIBRARY = $(DEPTH)/staticlib
-endif
-else
-# If EXPORT_LIBRARY has a value, we'll be installing there. We also need to cleanup there
-GARBAGE += $(foreach lib,$(LIBRARY),$(EXPORT_LIBRARY)/$(lib))
-endif
-endif # EXPORT_LIBRARY
-
-libs:: $(SUBMAKEFILES) $(MAKE_DIRS) $(HOST_LIBRARY) $(LIBRARY) $(SHARED_LIBRARY) $(IMPORT_LIBRARY) $(HOST_PROGRAM) $(PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(SIMPLE_PROGRAMS) $(JAVA_LIBRARY)
-ifndef NO_DIST_INSTALL
-ifdef LIBRARY
-ifdef EXPORT_LIBRARY # Stage libs that will be linked into a static build
-	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(EXPORT_LIBRARY)
-endif # EXPORT_LIBRARY
-ifdef DIST_INSTALL
-ifdef IS_COMPONENT
-	$(error Shipping static component libs makes no sense.)
-else
-	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(DIST)/lib
-endif
-endif # DIST_INSTALL
-endif # LIBRARY
-ifdef SHARED_LIBRARY
-ifdef IS_COMPONENT
-	$(INSTALL) $(IFLAGS2) $(SHARED_LIBRARY) $(FINAL_TARGET)/components
-	$(ELF_DYNSTR_GC) $(FINAL_TARGET)/components/$(SHARED_LIBRARY)
-ifndef NO_COMPONENTS_MANIFEST
-	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/chrome.manifest "manifest components/components.manifest"
-	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/components/components.manifest "binary-component $(SHARED_LIBRARY)"
-endif
-else # ! IS_COMPONENT
-ifneq (,$(filter OS2 WINNT,$(OS_ARCH)))
-ifndef NO_INSTALL_IMPORT_LIBRARY
-	$(INSTALL) $(IFLAGS2) $(IMPORT_LIBRARY) $(DIST)/lib
-endif
-else
-	$(INSTALL) $(IFLAGS2) $(SHARED_LIBRARY) $(DIST)/lib
-endif
-	$(INSTALL) $(IFLAGS2) $(SHARED_LIBRARY) $(FINAL_TARGET)
-endif # IS_COMPONENT
-endif # SHARED_LIBRARY
-ifdef PROGRAM
-	$(INSTALL) $(IFLAGS2) $(PROGRAM) $(FINAL_TARGET)
-endif
-ifdef SIMPLE_PROGRAMS
-	$(INSTALL) $(IFLAGS2) $(SIMPLE_PROGRAMS) $(FINAL_TARGET)
-endif
-ifdef HOST_PROGRAM
-	$(INSTALL) $(IFLAGS2) $(HOST_PROGRAM) $(DIST)/host/bin
-endif
-ifdef HOST_SIMPLE_PROGRAMS
-	$(INSTALL) $(IFLAGS2) $(HOST_SIMPLE_PROGRAMS) $(DIST)/host/bin
-endif
-ifdef HOST_LIBRARY
-	$(INSTALL) $(IFLAGS1) $(HOST_LIBRARY) $(DIST)/host/lib
-endif
-ifdef JAVA_LIBRARY
-ifdef IS_COMPONENT
-	$(INSTALL) $(IFLAGS1) $(JAVA_LIBRARY) $(FINAL_TARGET)/components
-else
-	$(INSTALL) $(IFLAGS1) $(JAVA_LIBRARY) $(FINAL_TARGET)
-endif
-endif # JAVA_LIBRARY
-endif # !NO_DIST_INSTALL
-	$(LOOP_OVER_DIRS)
+include $(topsrcdir)/config/makefiles/target_libs.mk
 
 ##############################################
-
 ifndef NO_PROFILE_GUIDED_OPTIMIZE
 ifdef MOZ_PROFILE_USE
 ifeq ($(OS_ARCH)_$(GNU_CC), WINNT_)
 # When building with PGO, we have to make sure to re-link
 # in the MOZ_PROFILE_USE phase if we linked in the
 # MOZ_PROFILE_GENERATE phase. We'll touch this pgo.relink
 # file in the link rule in the GENERATE phase to indicate
 # that we need a relink.
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -2734,18 +2734,17 @@ nsDocument::GetActiveElement(nsIDOMEleme
     // be safe and make sure the element is from this document
     if (focusedContent && focusedContent->GetOwnerDoc() == this) {
       CallQueryInterface(focusedContent, aElement);
       return NS_OK;
     }
   }
 
   // No focused element anywhere in this document.  Try to get the BODY.
-  nsCOMPtr<nsIDOMHTMLDocument> htmlDoc =
-    do_QueryInterface(static_cast<nsIDocument*>(this));
+  nsCOMPtr<nsIDOMHTMLDocument> htmlDoc = do_QueryObject(this);
   if (htmlDoc) {
     nsCOMPtr<nsIDOMHTMLElement> bodyElement;
     htmlDoc->GetBody(getter_AddRefs(bodyElement));
     if (bodyElement) {
       *aElement = bodyElement;
       NS_ADDREF(*aElement);
     }
     // Because of IE compatibility, return null when html document doesn't have
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -452,18 +452,17 @@ nsFrameMessageManager::ReceiveMessage(ns
         if (JS_ObjectIsCallable(ctx, object)) {
           // If the listener is a JS function:
           funval = OBJECT_TO_JSVAL(object);
 
           // A small hack to get 'this' value right on content side where
           // messageManager is wrapped in TabChildGlobal.
           nsCOMPtr<nsISupports> defaultThisValue;
           if (mChrome) {
-            defaultThisValue =
-              do_QueryInterface(static_cast<nsIContentFrameMessageManager*>(this));
+            defaultThisValue = do_QueryObject(this);
           } else {
             defaultThisValue = aTarget;
           }
           nsContentUtils::WrapNative(ctx,
                                      JS_GetGlobalForObject(ctx, object),
                                      defaultThisValue, &thisValue, nsnull, PR_TRUE);
         } else {
           // If the listener is a JS object which has receiveMessage function:
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -4869,18 +4869,17 @@ nsGenericElement::UnsetAttr(PRInt32 aNam
     nsNodeUtils::AttributeChanged(this, aNameSpaceID, aName,
                                   nsIDOMMutationEvent::REMOVAL);
   }
 
   rv = AfterSetAttr(aNameSpaceID, aName, nsnull, aNotify);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (hasMutationListeners) {
-    nsCOMPtr<nsIDOMEventTarget> node =
-      do_QueryInterface(static_cast<nsIContent *>(this));
+    nsCOMPtr<nsIDOMEventTarget> node = do_QueryObject(this);
     nsMutationEvent mutation(PR_TRUE, NS_MUTATION_ATTRMODIFIED);
 
     mutation.mRelatedNode = attrNode;
     mutation.mAttrName = aName;
 
     nsAutoString value;
     oldValue.ToString(value);
     if (!value.IsEmpty())
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -3964,16 +3964,17 @@ WebGLContext::CompileShader(nsIWebGLShad
         resources.MaxVertexTextureImageUnits = mGLMaxVertexTextureImageUnits;
         resources.MaxCombinedTextureImageUnits = mGLMaxTextureUnits;
         resources.MaxTextureImageUnits = mGLMaxTextureImageUnits;
         resources.MaxFragmentUniformVectors = mGLMaxFragmentUniformVectors;
         resources.MaxDrawBuffers = 1;
 
         compiler = ShConstructCompiler((ShShaderType) shader->ShaderType(),
                                        SH_WEBGL_SPEC,
+                                       gl->IsGLES2() ? SH_ESSL_OUTPUT : SH_GLSL_OUTPUT,
                                        &resources);
 
         nsPromiseFlatCString src(shader->Source());
         const char *s = src.get();
 
         if (!ShCompile(compiler, &s, 1, SH_OBJECT_CODE)) {
             int len = 0;
             ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &len);
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
@@ -334,17 +334,19 @@ public:
     nsCanvasRenderingContext2D();
     virtual ~nsCanvasRenderingContext2D();
 
     nsresult Redraw();
 
     // nsICanvasRenderingContextInternal
     NS_IMETHOD SetCanvasElement(nsHTMLCanvasElement* aParentCanvas);
     NS_IMETHOD SetDimensions(PRInt32 width, PRInt32 height);
+    void Initialize(nsIDocShell *shell, PRInt32 width, PRInt32 height);
     NS_IMETHOD InitializeWithSurface(nsIDocShell *shell, gfxASurface *surface, PRInt32 width, PRInt32 height);
+    PRBool EnsureSurface();
     NS_IMETHOD Render(gfxContext *ctx, gfxPattern::GraphicsFilter aFilter);
     NS_IMETHOD GetInputStream(const char* aMimeType,
                               const PRUnichar* aEncoderOptions,
                               nsIInputStream **aStream);
     NS_IMETHOD GetThebesSurface(gfxASurface **surface);
     mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot()
         { return nsnull; }
 
@@ -375,17 +377,17 @@ public:
         STYLE_SHADOW,
         STYLE_MAX
     };
 
     class PathAutoSaveRestore
     {
     public:
         PathAutoSaveRestore(nsCanvasRenderingContext2D* aCtx) :
-            mContext(aCtx->mThebes)
+          mContext(aCtx->mThebes)
         {
             if (aCtx->mHasPath) {
                 mPath = mContext->CopyPath();
             }
         }
         ~PathAutoSaveRestore()
         {
             mContext->NewPath();
@@ -455,22 +457,26 @@ protected:
     PRPackedBool mIPC;
 
     // the canvas element we're a context of
     nsCOMPtr<nsIDOMHTMLCanvasElement> mCanvasElement;
     nsHTMLCanvasElement *HTMLCanvasElement() {
         return static_cast<nsHTMLCanvasElement*>(mCanvasElement.get());
     }
 
+    // Initialize the Thebes rendering context
+    void CreateThebes();
+
     // If mCanvasElement is not provided, then a docshell is
     nsCOMPtr<nsIDocShell> mDocShell;
 
     // our drawing surfaces, contexts, and layers
     nsRefPtr<gfxContext> mThebes;
     nsRefPtr<gfxASurface> mSurface;
+    PRPackedBool mSurfaceCreated;
 
     PRUint32 mSaveCount;
 
     /**
      * Flag to avoid duplicate calls to InvalidateFrame. Set to true whenever
      * Redraw is called, reset to false when Render is called.
      */
     PRPackedBool mIsEntireFrameInvalid;
@@ -522,30 +528,40 @@ protected:
     /**
      * Checks the current state to determine if an intermediate surface would
      * be necessary to complete a drawing operation. Does not check the
      * condition pertaining to global alpha and patterns since that does not
      * pertain to all drawing operations.
      */
     PRBool NeedToUseIntermediateSurface()
     {
+        if (!mThebes) {
+            // Haven't created a surface yet, default is OVER.
+            return OperatorAffectsUncoveredAreas(gfxContext::OPERATOR_OVER);
+        }
+     
         // certain operators always need an intermediate surface, except
         // with quartz since quartz does compositing differently than cairo
         return OperatorAffectsUncoveredAreas(mThebes->CurrentOperator());
 
         // XXX there are other unhandled cases but they should be investigated
         // first to ensure we aren't using an intermediate surface unecessarily
     }
 
     /**
      * If the current operator is "source" then clear the destination before we
      * draw into it, to simulate the effect of an unbounded source operator.
      */
     void ClearSurfaceForUnboundedSource()
     {
+        if (!mThebes) {
+            // Haven't created a surface yet, default is OVER.
+            return;
+        }
+
         gfxContext::GraphicsOperator current = mThebes->CurrentOperator();
         if (current != gfxContext::OPERATOR_SOURCE)
             return;
         mThebes->SetOperator(gfxContext::OPERATOR_CLEAR);
         // It doesn't really matter what the source is here, since Paint
         // isn't bounded by the source and the mask covers the entire clip
         // region.
         mThebes->Paint();
@@ -592,18 +608,17 @@ protected:
      * Draws a rectangle in the given style; used by FillRect and StrokeRect.
      */
     nsresult DrawRect(const gfxRect& rect, Style style);
 
     /**
      * Gets the pres shell from either the canvas element or the doc shell
      */
     nsIPresShell *GetPresShell() {
-      nsCOMPtr<nsIContent> content =
-        do_QueryInterface(static_cast<nsIDOMHTMLCanvasElement*>(mCanvasElement));
+      nsCOMPtr<nsIContent> content = do_QueryObject(mCanvasElement);
       if (content) {
         nsIDocument* ownerDoc = content->GetOwnerDoc();
         return ownerDoc ? ownerDoc->GetShell() : nsnull;
       }
       if (mDocShell) {
         nsCOMPtr<nsIPresShell> shell;
         mDocShell->GetPresShell(getter_AddRefs(shell));
         return shell.get();
@@ -960,16 +975,20 @@ nsCanvasRenderingContext2D::ApplyStyle(S
     if (mLastStyle == aWhichStyle &&
         !mDirtyStyle[aWhichStyle] &&
         aUseGlobalAlpha)
     {
         // nothing to do, this is already the set style
         return;
     }
 
+    if (!EnsureSurface()) {
+      return;
+    }
+
     // if not using global alpha, don't optimize with dirty bit
     if (aUseGlobalAlpha)
         mDirtyStyle[aWhichStyle] = PR_FALSE;
     mLastStyle = aWhichStyle;
 
     nsCanvasPattern* pattern = CurrentState().patternStyles[aWhichStyle];
     if (pattern) {
         if (mCanvasElement)
@@ -1054,135 +1073,169 @@ nsCanvasRenderingContext2D::RedrawUser(c
     }
 
     return Redraw(mThebes->UserToDevice(r));
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::SetDimensions(PRInt32 width, PRInt32 height)
 {
-    nsRefPtr<gfxASurface> surface;
-
-    // Check that the dimensions are sane
-    gfxIntSize size(width, height);
-    if (gfxASurface::CheckSurfaceSize(size, 0xffff)) {
-        // Zero sized surfaces have problems, so just use a 1 by 1.
-        if (height == 0 || width == 0) {
-            mZero = PR_TRUE;
-            height = 1;
-            width = 1;
-        } else {
-            mZero = PR_FALSE;
-        }
-
-        gfxASurface::gfxImageFormat format = GetImageFormat();
-
-        if (!PR_GetEnv("MOZ_CANVAS_IMAGE_SURFACE")) {
-            nsCOMPtr<nsIContent> content =
-                do_QueryInterface(static_cast<nsIDOMHTMLCanvasElement*>(mCanvasElement));
-            nsIDocument* ownerDoc = nsnull;
-            if (content)
-                ownerDoc = content->GetOwnerDoc();
-            nsRefPtr<LayerManager> layerManager = nsnull;
-
-            if (ownerDoc)
-              layerManager =
-                nsContentUtils::PersistentLayerManagerForDocument(ownerDoc);
-
-            if (layerManager) {
-              surface = layerManager->CreateOptimalSurface(gfxIntSize(width, height), format);
-            } else {
-              surface = gfxPlatform::GetPlatform()->
-                CreateOffscreenSurface(gfxIntSize(width, height), gfxASurface::ContentFromFormat(format));
-            }
-        }
-
-        if (!surface || surface->CairoStatus()) {
-            // If we couldn't create a surface of the type we want, fall back
-            // to an image surface. This lets us handle surface sizes that
-            // the underlying cairo backend might not handle.
-            surface = new gfxImageSurface(gfxIntSize(width, height), format);
-            if (!surface || surface->CairoStatus()) {
-                surface = nsnull;
-            }
-        }
-    }
-    if (surface) {
-        if (gCanvasMemoryReporter == nsnull) {
-            gCanvasMemoryReporter = new NS_MEMORY_REPORTER_NAME(CanvasMemory);
-            NS_RegisterMemoryReporter(gCanvasMemoryReporter);
-        }
-
-        gCanvasMemoryUsed += width * height * 4;
-        JSContext* context = nsContentUtils::GetCurrentJSContext();
-        if (context) {
-            JS_updateMallocCounter(context, width * height * 4);
-        }
-    }
-
-    return InitializeWithSurface(NULL, surface, width, height);
+    Initialize(NULL, width, height);
+    return NS_OK;
 }
 
-NS_IMETHODIMP
-nsCanvasRenderingContext2D::InitializeWithSurface(nsIDocShell *docShell, gfxASurface *surface, PRInt32 width, PRInt32 height) {
+void
+nsCanvasRenderingContext2D::Initialize(nsIDocShell *docShell, PRInt32 width, PRInt32 height) 
+{
     Reset();
 
     NS_ASSERTION(!docShell ^ !mCanvasElement, "Cannot set both docshell and canvas element");
     mDocShell = docShell;
 
     mWidth = width;
     mHeight = height;
 
-    mSurface = surface;
-    mThebes = surface ? new gfxContext(mSurface) : nsnull;
     mResetLayer = PR_TRUE;
-
-    /* Create dummy surfaces here */
-    if (mSurface == nsnull || mSurface->CairoStatus() != 0 ||
-        mThebes == nsnull || mThebes->HasError())
-    {
-        mSurface = new gfxImageSurface(gfxIntSize(1,1), gfxASurface::ImageFormatARGB32);
-        mThebes = new gfxContext(mSurface);
-    } else {
-        mValid = PR_TRUE;
-    }
+    mValid = PR_TRUE;
+    mSurfaceCreated = PR_FALSE;
 
     // set up the initial canvas defaults
     mStyleStack.Clear();
     mSaveCount = 0;
 
     ContextState *state = mStyleStack.AppendElement();
     state->globalAlpha = 1.0;
 
     state->colorStyles[STYLE_FILL] = NS_RGB(0,0,0);
     state->colorStyles[STYLE_STROKE] = NS_RGB(0,0,0);
     state->colorStyles[STYLE_SHADOW] = NS_RGBA(0,0,0,0);
     DirtyAllStyles();
 
+    // always force a redraw, because if the surface dimensions were reset
+    // then the surface became cleared, and we need to redraw everything.
+    Redraw();
+
+    return;
+}
+
+void
+nsCanvasRenderingContext2D::CreateThebes()
+{
+    mThebes = new gfxContext(mSurface);
+    mSurfaceCreated = PR_TRUE;
+    
     mThebes->SetOperator(gfxContext::OPERATOR_CLEAR);
     mThebes->NewPath();
     mThebes->Rectangle(gfxRect(0, 0, mWidth, mHeight));
     mThebes->Fill();
 
     mThebes->SetLineWidth(1.0);
     mThebes->SetOperator(gfxContext::OPERATOR_OVER);
     mThebes->SetMiterLimit(10.0);
     mThebes->SetLineCap(gfxContext::LINE_CAP_BUTT);
     mThebes->SetLineJoin(gfxContext::LINE_JOIN_MITER);
-    mThebes->SetFillRule(gfxContext::FILL_RULE_WINDING);
 
     mThebes->NewPath();
-
-    // always force a redraw, because if the surface dimensions were reset
-    // then the surface became cleared, and we need to redraw everything.
-    Redraw();
-
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContext2D::InitializeWithSurface(nsIDocShell *docShell, 
+                                                  gfxASurface *surface, 
+                                                  PRInt32 width, 
+                                                  PRInt32 height)
+{
+    Initialize(docShell, width, height);
+    
+    mSurface = surface;
+    CreateThebes();
     return mValid ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
 }
 
+PRBool
+nsCanvasRenderingContext2D::EnsureSurface()
+{
+    if (!mValid) {
+        return PR_FALSE;
+    }
+
+    if (mSurface && mThebes && mSurfaceCreated) {
+        if (mSurface->CairoStatus()) {
+            return PR_FALSE;
+        }
+        return PR_TRUE;
+    }
+    
+    nsRefPtr<gfxASurface> surface;
+
+    // Check that the dimensions are sane
+    if (gfxASurface::CheckSurfaceSize(gfxIntSize(mWidth, mHeight), 0xffff)) {
+        // Zero sized surfaces have problems, so just use a 1 by 1.
+        if (mHeight == 0 || mWidth == 0) {
+            mZero = PR_TRUE;
+            mHeight = 1;
+            mWidth = 1;
+        } else {
+            mZero = PR_FALSE;
+        }
+
+        gfxASurface::gfxImageFormat format = GetImageFormat();
+
+        if (!PR_GetEnv("MOZ_CANVAS_IMAGE_SURFACE")) {
+            nsCOMPtr<nsIContent> content = do_QueryObject(mCanvasElement);
+            nsIDocument* ownerDoc = nsnull;
+            if (content)
+                ownerDoc = content->GetOwnerDoc();
+            nsRefPtr<LayerManager> layerManager = nsnull;
+
+            if (ownerDoc)
+              layerManager =
+                nsContentUtils::PersistentLayerManagerForDocument(ownerDoc);
+
+            if (layerManager) {
+              surface = layerManager->CreateOptimalSurface(gfxIntSize(mWidth, mHeight), format);
+            } else {
+              surface = gfxPlatform::GetPlatform()->
+                CreateOffscreenSurface(gfxIntSize(mWidth, mHeight), gfxASurface::ContentFromFormat(format));
+            }
+        }
+
+        if (!surface || surface->CairoStatus()) {
+            // If we couldn't create a surface of the type we want, fall back
+            // to an image surface. This lets us handle surface sizes that
+            // the underlying cairo backend might not handle.
+            surface = new gfxImageSurface(gfxIntSize(mWidth, mHeight), format);
+            if (!surface || surface->CairoStatus()) {
+                surface = nsnull;
+            }
+        }
+    }
+    if (surface) {
+        if (gCanvasMemoryReporter == nsnull) {
+            gCanvasMemoryReporter = new NS_MEMORY_REPORTER_NAME(CanvasMemory);
+            NS_RegisterMemoryReporter(gCanvasMemoryReporter);
+        }
+
+        gCanvasMemoryUsed += mWidth * mHeight * 4;
+        JSContext* context = nsContentUtils::GetCurrentJSContext();
+        if (context) {
+            JS_updateMallocCounter(context, mWidth * mHeight * 4);
+        }
+    } else {
+        return PR_FALSE;
+    }
+
+    mSurface = surface;
+    CreateThebes();
+
+    if (mSurface->CairoStatus()) {
+        return PR_FALSE;
+    }
+    return PR_TRUE;
+}
+
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::SetIsOpaque(PRBool isOpaque)
 {
     if (isOpaque == mOpaque)
         return NS_OK;
 
     mOpaque = isOpaque;
 
@@ -1214,19 +1267,17 @@ nsCanvasRenderingContext2D::SetIsIPC(PRB
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::Render(gfxContext *ctx, gfxPattern::GraphicsFilter aFilter)
 {
     nsresult rv = NS_OK;
 
-    if (!mValid || !mSurface ||
-        mSurface->CairoStatus() ||
-        mThebes->HasError())
+    if (!EnsureSurface())
         return NS_ERROR_FAILURE;
 
     nsRefPtr<gfxPattern> pat = new gfxPattern(mSurface);
 
     pat->SetFilter(aFilter);
     pat->SetExtend(gfxPattern::EXTEND_PAD);
 
     gfxContext::GraphicsOperator op = ctx->CurrentOperator();
@@ -1245,19 +1296,17 @@ nsCanvasRenderingContext2D::Render(gfxCo
     return rv;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::GetInputStream(const char *aMimeType,
                                            const PRUnichar *aEncoderOptions,
                                            nsIInputStream **aStream)
 {
-    if (!mValid || !mSurface ||
-        mSurface->CairoStatus() ||
-        mThebes->HasError())
+    if (!EnsureSurface())
         return NS_ERROR_FAILURE;
 
     nsresult rv;
     const char encoderPrefix[] = "@mozilla.org/image/encoder;2?type=";
     nsAutoArrayPtr<char> conid(new (std::nothrow) char[strlen(encoderPrefix) + strlen(aMimeType) + 1]);
 
     if (!conid)
         return NS_ERROR_OUT_OF_MEMORY;
@@ -1332,26 +1381,32 @@ nsCanvasRenderingContext2D::GetCanvas(ns
 
 //
 // state
 //
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::Save()
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     ContextState state = CurrentState();
     mStyleStack.AppendElement(state);
     mThebes->Save();
     mSaveCount++;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::Restore()
 {
+    if (!EnsureSurface()) 
+        return NS_ERROR_FAILURE;
+
     if (mSaveCount == 0)
         return NS_OK;
 
     mStyleStack.RemoveElementAt(mSaveCount);
     mThebes->Restore();
 
     mLastStyle = STYLE_MAX;
     DirtyAllStyles();
@@ -1362,96 +1417,120 @@ nsCanvasRenderingContext2D::Restore()
 
 //
 // transformations
 //
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::Scale(float x, float y)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     if (!FloatValidate(x,y))
         return NS_OK;
 
     mThebes->Scale(x, y);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::Rotate(float angle)
 {
+    if (!EnsureSurface()) 
+        return NS_ERROR_FAILURE;
+
     if (!FloatValidate(angle))
         return NS_OK;
 
     mThebes->Rotate(angle);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::Translate(float x, float y)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     if (!FloatValidate(x,y))
         return NS_OK;
 
     mThebes->Translate(gfxPoint(x, y));
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::Transform(float m11, float m12, float m21, float m22, float dx, float dy)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     if (!FloatValidate(m11,m12,m21,m22,dx,dy))
         return NS_OK;
 
     gfxMatrix matrix(m11, m12, m21, m22, dx, dy);
     mThebes->Multiply(matrix);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::SetTransform(float m11, float m12, float m21, float m22, float dx, float dy)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     if (!FloatValidate(m11,m12,m21,m22,dx,dy))
         return NS_OK;
 
     gfxMatrix matrix(m11, m12, m21, m22, dx, dy);
     mThebes->SetMatrix(matrix);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::SetMozCurrentTransform(JSContext* cx,
                                                    const jsval& matrix)
 {
     nsresult rv;
     gfxMatrix newCTM;
+    
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
 
     if (!JSValToMatrix(cx, matrix, &newCTM, &rv)) {
         return rv;
     }
 
     mThebes->SetMatrix(newCTM);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::GetMozCurrentTransform(JSContext* cx,
                                                    jsval* matrix)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     return MatrixToJSVal(mThebes->CurrentMatrix(), cx, matrix);
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::SetMozCurrentTransformInverse(JSContext* cx,
                                                           const jsval& matrix)
 {
     nsresult rv;
     gfxMatrix newCTMInverse;
+    
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
 
     if (!JSValToMatrix(cx, matrix, &newCTMInverse, &rv)) {
         return rv;
     }
 
     // XXX ERRMSG we need to report an error to developers here! (bug 329026)
     if (!newCTMInverse.IsSingular()) {
         mThebes->SetMatrix(newCTMInverse.Invert());
@@ -1643,32 +1722,38 @@ nsCanvasRenderingContext2D::GetFillStyle
 {
     return GetStyleAsStringOrInterface(aStr, aInterface, aType, STYLE_FILL);
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::SetMozFillRule(const nsAString& aString)
 {
     gfxContext::FillRule rule;
+    
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
 
     if (aString.EqualsLiteral("evenodd"))
         rule = gfxContext::FILL_RULE_EVEN_ODD;
     else if (aString.EqualsLiteral("nonzero"))
         rule = gfxContext::FILL_RULE_WINDING;
     else
         // XXX ERRMSG we need to report an error to developers here! (bug 329026)
         return NS_OK;
 
     mThebes->SetFillRule(rule);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::GetMozFillRule(nsAString& aString)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     switch (mThebes->CurrentFillRule()) {
     case gfxContext::FILL_RULE_WINDING:
         aString.AssignLiteral("nonzero"); break;
     case gfxContext::FILL_RULE_EVEN_ODD:
         aString.AssignLiteral("evenodd"); break;
     default:
         return NS_ERROR_FAILURE;
     }
@@ -1883,30 +1968,36 @@ nsCanvasRenderingContext2D::ShadowInitia
         return nsnull;
 
     return ctx;
 }
 
 void
 nsCanvasRenderingContext2D::ShadowFinalize(gfxAlphaBoxBlur& blur)
 {
+    if (!EnsureSurface())
+        return;
+
     ApplyStyle(STYLE_SHADOW);
     // canvas matrix was already applied, don't apply it twice, but do
     // apply the shadow offset
     gfxMatrix matrix = mThebes->CurrentMatrix();
     mThebes->IdentityMatrix();
     mThebes->Translate(CurrentState().shadowOffset);
 
     blur.Paint(mThebes);
     mThebes->SetMatrix(matrix);
 }
 
 nsresult
 nsCanvasRenderingContext2D::DrawPath(Style style, gfxRect *dirtyRect)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     PRBool doUseIntermediateSurface = PR_FALSE;
     
     if (mSurface->GetType() == gfxASurface::SurfaceTypeD2D) {
       if (style != STYLE_FILL) {
         // D2D does all operators correctly even if transparent areas of SOURCE
         // affect dest. We need to use an intermediate surface for STROKE because
         // we can't clip to the actual stroke shape easily, but prefer a geometric
         // clip over an intermediate surface for a FILL.
@@ -2024,16 +2115,19 @@ nsCanvasRenderingContext2D::DrawPath(Sty
 
 //
 // rects
 //
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::ClearRect(float x, float y, float w, float h)
 {
+    if (!mSurfaceCreated)
+        return NS_OK;
+
     if (!FloatValidate(x,y,w,h))
         return NS_OK;
 
     PathAutoSaveRestore pathSR(this);
     gfxContextAutoSaveRestore autoSR(mThebes);
 
     mThebes->SetOperator(gfxContext::OPERATOR_CLEAR);
     mThebes->NewPath();
@@ -2041,16 +2135,19 @@ nsCanvasRenderingContext2D::ClearRect(fl
     mThebes->Fill();
 
     return RedrawUser(mThebes->GetUserPathExtent());
 }
 
 nsresult
 nsCanvasRenderingContext2D::DrawRect(const gfxRect& rect, Style style)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     if (!FloatValidate(rect.X(), rect.Y(), rect.Width(), rect.Height()))
         return NS_OK;
 
     PathAutoSaveRestore pathSR(this);
 
     mThebes->NewPath();
     mThebes->Rectangle(rect);
 
@@ -2079,24 +2176,30 @@ nsCanvasRenderingContext2D::StrokeRect(f
 
 //
 // path bits
 //
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::BeginPath()
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     mHasPath = PR_FALSE;
     mThebes->NewPath();
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::ClosePath()
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     mThebes->ClosePath();
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::Fill()
 {
     gfxRect dirty;
@@ -2114,45 +2217,57 @@ nsCanvasRenderingContext2D::Stroke()
     if (NS_FAILED(rv))
         return rv;
     return RedrawUser(dirty);
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::Clip()
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     mThebes->Clip();
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::MoveTo(float x, float y)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     if (!FloatValidate(x,y))
         return NS_OK;
 
     mHasPath = PR_TRUE;
     mThebes->MoveTo(gfxPoint(x, y));
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::LineTo(float x, float y)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     if (!FloatValidate(x,y))
         return NS_OK;
 
     mHasPath = PR_TRUE;
     mThebes->LineTo(gfxPoint(x, y));
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::QuadraticCurveTo(float cpx, float cpy, float x, float y)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     if (!FloatValidate(cpx,cpy,x,y))
         return NS_OK;
 
     // we will always have a current point, since beginPath forces
     // a moveto(0,0)
     gfxPoint c = mThebes->CurrentPoint();
     gfxPoint p(x,y);
     gfxPoint cp(cpx, cpy);
@@ -2163,30 +2278,36 @@ nsCanvasRenderingContext2D::QuadraticCur
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::BezierCurveTo(float cp1x, float cp1y,
                                           float cp2x, float cp2y,
                                           float x, float y)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     if (!FloatValidate(cp1x,cp1y,cp2x,cp2y,x,y))
         return NS_OK;
 
     mHasPath = PR_TRUE;
     mThebes->CurveTo(gfxPoint(cp1x, cp1y),
                      gfxPoint(cp2x, cp2y),
                      gfxPoint(x, y));
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::ArcTo(float x1, float y1, float x2, float y2, float radius)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     if (!FloatValidate(x1,y1,x2,y2,radius))
         return NS_OK;
 
     if (radius < 0)
         return NS_ERROR_DOM_INDEX_SIZE_ERR;
 
     mHasPath = PR_TRUE;
 
@@ -2236,16 +2357,19 @@ nsCanvasRenderingContext2D::ArcTo(float 
         mThebes->Arc(gfxPoint(cx, cy), radius, angle0, angle1);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::Arc(float x, float y, float r, float startAngle, float endAngle, PRBool ccw)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     if (!FloatValidate(x,y,r,startAngle,endAngle))
         return NS_OK;
 
     if (r < 0.0)
         return NS_ERROR_DOM_INDEX_SIZE_ERR;
 
     gfxPoint p(x,y);
 
@@ -2255,16 +2379,19 @@ nsCanvasRenderingContext2D::Arc(float x,
     else
         mThebes->Arc(p, r, startAngle, endAngle);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::Rect(float x, float y, float w, float h)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     if (!FloatValidate(x,y,w,h))
         return NS_OK;
 
     mHasPath = PR_TRUE;
     mThebes->Rectangle(gfxRect(x, y, w, h));
     return NS_OK;
 }
 
@@ -2767,17 +2894,23 @@ nsCanvasRenderingContext2D::DrawOrMeasur
 
     // Clear the surface if we need to simulate unbounded SOURCE operator
     ClearSurfaceForUnboundedSource();
 
     nsCanvasBidiProcessor processor;
 
     GetAppUnitsValues(&processor.mAppUnitsPerDevPixel, NULL);
     processor.mPt = gfxPoint(aX, aY);
-    processor.mThebes = mThebes;
+    nsRefPtr<nsRenderingContext> ctx;
+    if (mThebes) {
+        processor.mThebes = mThebes;
+    } else {
+        ctx = presShell->GetReferenceRenderingContext();
+        processor.mThebes = ctx->ThebesContext(); 
+    }
     processor.mOp = aOp;
     processor.mBoundingBox = gfxRect(0, 0, 0, 0);
     processor.mDoMeasureBoundingBox = doDrawShadow || !mIsEntireFrameInvalid;
 
     processor.mFontgrp = GetCurrentFontStyle();
     NS_ASSERTION(processor.mFontgrp, "font group is null");
 
     nscoord totalWidthCoord;
@@ -2801,16 +2934,21 @@ nsCanvasRenderingContext2D::DrawOrMeasur
     float totalWidth = float(totalWidthCoord) / processor.mAppUnitsPerDevPixel;
     if (aWidth)
         *aWidth = totalWidth;
 
     // if only measuring, don't need to do any more work
     if (aOp==TEXT_DRAW_OPERATION_MEASURE)
         return NS_OK;
 
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
+    processor.mThebes = mThebes;
+
     // offset pt.x based on text align
     gfxFloat anchorX;
 
     if (CurrentState().textAlign == TEXT_ALIGN_CENTER)
         anchorX = .5;
     else if (CurrentState().textAlign == TEXT_ALIGN_LEFT ||
              (!isRTL && CurrentState().textAlign == TEXT_ALIGN_START) ||
              (isRTL && CurrentState().textAlign == TEXT_ALIGN_END))
@@ -3021,34 +3159,43 @@ nsCanvasRenderingContext2D::MakeTextRun(
 
 
 //
 // line caps/joins
 //
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::SetLineWidth(float width)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     if (!FloatValidate(width) || width <= 0.0)
         return NS_OK;
 
     mThebes->SetLineWidth(width);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::GetLineWidth(float *width)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+ 
     gfxFloat d = mThebes->CurrentLineWidth();
     *width = static_cast<float>(d);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::SetLineCap(const nsAString& capstyle)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     gfxContext::GraphicsLineCap cap;
 
     if (capstyle.EqualsLiteral("butt"))
         cap = gfxContext::LINE_CAP_BUTT;
     else if (capstyle.EqualsLiteral("round"))
         cap = gfxContext::LINE_CAP_ROUND;
     else if (capstyle.EqualsLiteral("square"))
         cap = gfxContext::LINE_CAP_SQUARE;
@@ -3058,16 +3205,19 @@ nsCanvasRenderingContext2D::SetLineCap(c
 
     mThebes->SetLineCap(cap);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::GetLineCap(nsAString& capstyle)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     gfxContext::GraphicsLineCap cap = mThebes->CurrentLineCap();
 
     if (cap == gfxContext::LINE_CAP_BUTT)
         capstyle.AssignLiteral("butt");
     else if (cap == gfxContext::LINE_CAP_ROUND)
         capstyle.AssignLiteral("round");
     else if (cap == gfxContext::LINE_CAP_SQUARE)
         capstyle.AssignLiteral("square");
@@ -3075,16 +3225,19 @@ nsCanvasRenderingContext2D::GetLineCap(n
         return NS_ERROR_FAILURE;
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::SetLineJoin(const nsAString& joinstyle)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     gfxContext::GraphicsLineJoin j;
 
     if (joinstyle.EqualsLiteral("round"))
         j = gfxContext::LINE_JOIN_ROUND;
     else if (joinstyle.EqualsLiteral("bevel"))
         j = gfxContext::LINE_JOIN_BEVEL;
     else if (joinstyle.EqualsLiteral("miter"))
         j = gfxContext::LINE_JOIN_MITER;
@@ -3094,16 +3247,19 @@ nsCanvasRenderingContext2D::SetLineJoin(
 
     mThebes->SetLineJoin(j);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::GetLineJoin(nsAString& joinstyle)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     gfxContext::GraphicsLineJoin j = mThebes->CurrentLineJoin();
 
     if (j == gfxContext::LINE_JOIN_ROUND)
         joinstyle.AssignLiteral("round");
     else if (j == gfxContext::LINE_JOIN_BEVEL)
         joinstyle.AssignLiteral("bevel");
     else if (j == gfxContext::LINE_JOIN_MITER)
         joinstyle.AssignLiteral("miter");
@@ -3111,56 +3267,71 @@ nsCanvasRenderingContext2D::GetLineJoin(
         return NS_ERROR_FAILURE;
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::SetMiterLimit(float miter)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     if (!FloatValidate(miter) || miter <= 0.0)
         return NS_OK;
 
     mThebes->SetMiterLimit(miter);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::GetMiterLimit(float *miter)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     gfxFloat d = mThebes->CurrentMiterLimit();
     *miter = static_cast<float>(d);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::SetMozDash(JSContext *cx, const jsval& patternArray)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     AutoFallibleTArray<gfxFloat, 10> dashes;
     nsresult rv = JSValToDashArray(cx, patternArray, dashes);
     if (NS_SUCCEEDED(rv)) {
         mThebes->SetDash(dashes.Elements(), dashes.Length(),
                          mThebes->CurrentDashOffset());
     }
     return rv;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::GetMozDash(JSContext* cx, jsval* dashArray)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     AutoFallibleTArray<gfxFloat, 10> dashes;
     if (!mThebes->CurrentDash(dashes, nsnull)) {
         dashes.SetLength(0);
     }
     return DashArrayToJSVal(dashes, cx, dashArray);
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::SetMozDashOffset(float offset)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     if (!FloatValidate(offset)) {
         return NS_ERROR_ILLEGAL_VALUE;
     }
 
     AutoFallibleTArray<gfxFloat, 10> dashes;
     if (!mThebes->CurrentDash(dashes, nsnull)) {
         // Either no dash is set or the cairo call failed.  Either
         // way, eat the error.
@@ -3175,23 +3346,29 @@ nsCanvasRenderingContext2D::SetMozDashOf
                      gfxFloat(offset));
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::GetMozDashOffset(float* offset)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     *offset = float(mThebes->CurrentDashOffset());
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::IsPointInPath(float x, float y, PRBool *retVal)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     if (!FloatValidate(x,y)) {
         *retVal = PR_FALSE;
         return NS_OK;
     }
 
     gfxPoint pt(x, y);
     *retVal = mThebes->PointInFill(mThebes->DeviceToUser(pt));
     return NS_OK;
@@ -3209,16 +3386,19 @@ nsCanvasRenderingContext2D::IsPointInPat
 //   -- render the region defined by (sx,sy,sw,wh) in image-local space into the region (dx,dy,dw,dh) on the canvas
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::DrawImage(nsIDOMElement *imgElt, float a1,
                                       float a2, float a3, float a4, float a5,
                                       float a6, float a7, float a8,
                                       PRUint8 optional_argc)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     if (!imgElt) {
         return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
     }
 
     nsCOMPtr<nsIContent> content = do_QueryInterface(imgElt);
     nsHTMLCanvasElement* canvas = nsHTMLCanvasElement::FromContent(content);
     if (canvas) {
         nsIntSize size = canvas->GetSize();
@@ -3393,16 +3573,19 @@ nsCanvasRenderingContext2D::DrawImage(ns
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::SetGlobalCompositeOperation(const nsAString& op)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     gfxContext::GraphicsOperator thebes_op;
 
 #define CANVAS_OP_TO_THEBES_OP(cvsop,thebesop) \
     if (op.EqualsLiteral(cvsop))   \
         thebes_op = gfxContext::OPERATOR_##thebesop;
 
     CANVAS_OP_TO_THEBES_OP("copy", SOURCE)
     else CANVAS_OP_TO_THEBES_OP("destination-atop", DEST_ATOP)
@@ -3422,16 +3605,19 @@ nsCanvasRenderingContext2D::SetGlobalCom
 
     mThebes->SetOperator(thebes_op);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::GetGlobalCompositeOperation(nsAString& op)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     gfxContext::GraphicsOperator thebes_op = mThebes->CurrentOperator();
 
 #define CANVAS_OP_TO_THEBES_OP(cvsop,thebesop) \
     if (thebes_op == gfxContext::OPERATOR_##thebesop) \
         op.AssignLiteral(cvsop);
 
     CANVAS_OP_TO_THEBES_OP("copy", SOURCE)
     else CANVAS_OP_TO_THEBES_OP("destination-atop", DEST_ATOP)
@@ -3452,16 +3638,19 @@ nsCanvasRenderingContext2D::GetGlobalCom
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::DrawWindow(nsIDOMWindow* aWindow, float aX, float aY,
                                        float aW, float aH,
                                        const nsAString& aBGColor,
                                        PRUint32 flags)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     NS_ENSURE_ARG(aWindow != nsnull);
 
     // protect against too-large surfaces that will cause allocation
     // or overflow issues
     if (!gfxASurface::CheckSurfaceSize(gfxIntSize(PRInt32(aW), PRInt32(aH)),
                                        0xffff))
         return NS_ERROR_FAILURE;
 
@@ -3542,16 +3731,19 @@ nsCanvasRenderingContext2D::DrawWindow(n
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::AsyncDrawXULElement(nsIDOMXULElement* aElem, float aX, float aY,
                                                 float aW, float aH,
                                                 const nsAString& aBGColor,
                                                 PRUint32 flags)
 {
+    if (!EnsureSurface())
+        return NS_ERROR_FAILURE;
+
     NS_ENSURE_ARG(aElem != nsnull);
 
     // We can't allow web apps to call this until we fix at least the
     // following potential security issues:
     // -- rendering cross-domain IFRAMEs and then extracting the results
     // -- rendering the user's theme and then extracting the results
     // -- rendering native anonymous content (e.g., file input paths;
     // scrollbars should be allowed)
@@ -3655,17 +3847,17 @@ nsCanvasRenderingContext2D::GetImageData
     /* Should never be called -- GetImageData_explicit is the QS entry point */
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::GetImageData_explicit(PRInt32 x, PRInt32 y, PRUint32 w, PRUint32 h,
                                                   PRUint8 *aData, PRUint32 aDataLen)
 {
-    if (!mValid)
+    if (!EnsureSurface())
         return NS_ERROR_FAILURE;
 
     if (!mCanvasElement && !mDocShell) {
         NS_ERROR("No canvas element and no docshell in GetImageData!!!");
         return NS_ERROR_DOM_SECURITY_ERR;
     }
 
     // Check only if we have a canvas element; if we were created with a docshell,
@@ -3787,17 +3979,17 @@ nsCanvasRenderingContext2D::PutImageData
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::PutImageData_explicit(PRInt32 x, PRInt32 y, PRUint32 w, PRUint32 h,
                                                   unsigned char *aData, PRUint32 aDataLen,
                                                   PRBool hasDirtyRect, PRInt32 dirtyX, PRInt32 dirtyY,
                                                   PRInt32 dirtyWidth, PRInt32 dirtyHeight)
 {
-    if (!mValid)
+    if (!EnsureSurface())
         return NS_ERROR_FAILURE;
 
     if (w == 0 || h == 0)
         return NS_ERROR_DOM_SYNTAX_ERR;
 
     gfxRect dirtyRect;
     gfxRect imageDataRect(0, 0, w, h);
 
@@ -3893,17 +4085,17 @@ nsCanvasRenderingContext2D::PutImageData
     mThebes->Fill();
 
     return Redraw(dirtyRect);
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::GetThebesSurface(gfxASurface **surface)
 {
-    if (!mSurface) {
+    if (!EnsureSurface()) {
         *surface = nsnull;
         return NS_ERROR_NOT_AVAILABLE;
     }
 
     *surface = mSurface.get();
     NS_ADDREF(*surface);
 
     return NS_OK;
@@ -3949,17 +4141,17 @@ private:
   nsRefPtr<nsHTMLCanvasElement> mContent;
 };
 
 already_AddRefed<CanvasLayer>
 nsCanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
                                            CanvasLayer *aOldLayer,
                                            LayerManager *aManager)
 {
-    if (!mValid)
+    if (!EnsureSurface()) 
         return nsnull;
 
     if (!mResetLayer && aOldLayer &&
         aOldLayer->HasUserData(&g2DContextLayerUserData)) {
         NS_ADDREF(aOldLayer);
         return aOldLayer;
     }
 
--- a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
@@ -600,18 +600,17 @@ protected:
 
     return CurrentState().op;
   }
 
   /**
     * Gets the pres shell from either the canvas element or the doc shell
     */
   nsIPresShell *GetPresShell() {
-    nsCOMPtr<nsIContent> content =
-      do_QueryInterface(static_cast<nsIDOMHTMLCanvasElement*>(mCanvasElement));
+    nsCOMPtr<nsIContent> content = do_QueryObject(mCanvasElement);
     if (content) {
       nsIDocument* ownerDoc = content->GetOwnerDoc();
       return ownerDoc ? ownerDoc->GetShell() : nsnull;
     }
     if (mDocShell) {
       nsCOMPtr<nsIPresShell> shell;
       mDocShell->GetPresShell(getter_AddRefs(shell));
       return shell.get();
@@ -1230,18 +1229,17 @@ nsCanvasRenderingContext2DAzure::SetDime
     mZero = PR_FALSE;
   }
 
   // Check that the dimensions are sane
   IntSize size(width, height);
   if (size.width <= 0xFFFF && size.height <= 0xFFFF &&
       size.width >= 0 && size.height >= 0) {
     SurfaceFormat format = GetSurfaceFormat();
-    nsCOMPtr<nsIContent> content =
-      do_QueryInterface(static_cast<nsIDOMHTMLCanvasElement*>(mCanvasElement));
+    nsCOMPtr<nsIContent> content = do_QueryObject(mCanvasElement);
     nsIDocument* ownerDoc = nsnull;
     if (content) {
       ownerDoc = content->GetOwnerDoc();
     }
 
     nsRefPtr<LayerManager> layerManager = nsnull;
 
     if (ownerDoc) {
--- a/content/canvas/test/webgl/conformance/oes-texture-float.html
+++ b/content/canvas/test/webgl/conformance/oes-texture-float.html
@@ -80,17 +80,18 @@ if (!gl) {
   runTextureCreationTest(testProgram, false);
 
   if (!gl.getExtension("OES_texture_float")) {
       testPassed("No OES_texture_float support -- this is legal");
   } else {
       testPassed("Successfully enabled OES_texture_float extension");
       runTextureCreationTest(testProgram, true);
       runRenderTargetTest(testProgram);
-      runUniqueObjectTest();
+      // bug 683216, see the discussion in bug 630672
+      // runUniqueObjectTest();
   }
 }
 
 // Needs to be global for shouldBe to see it.
 var pixels;
 
 function allocateTexture()
 {
new file mode 100644
--- /dev/null
+++ b/content/canvas/test/webgl/remove-uniqueObjectTest.patch
@@ -0,0 +1,25 @@
+# HG changeset patch
+# Parent 6c8a909977d32284bbddd60a45e1780e824b5d7c
+diff --git a/content/canvas/test/webgl/conformance/oes-texture-float.html b/content/canvas/test/webgl/conformance/oes-texture-float.html
+--- a/content/canvas/test/webgl/conformance/oes-texture-float.html
++++ b/content/canvas/test/webgl/conformance/oes-texture-float.html
+@@ -80,17 +80,18 @@ if (!gl) {
+   runTextureCreationTest(testProgram, false);
+ 
+   if (!gl.getExtension("OES_texture_float")) {
+       testPassed("No OES_texture_float support -- this is legal");
+   } else {
+       testPassed("Successfully enabled OES_texture_float extension");
+       runTextureCreationTest(testProgram, true);
+       runRenderTargetTest(testProgram);
+-      runUniqueObjectTest();
++      // bug 683216, see the discussion in bug 630672
++      // runUniqueObjectTest();
+   }
+ }
+ 
+ // Needs to be global for shouldBe to see it.
+ var pixels;
+ 
+ function allocateTexture()
+ {
--- a/content/html/content/src/nsHTMLFormElement.cpp
+++ b/content/html/content/src/nsHTMLFormElement.cpp
@@ -1209,18 +1209,17 @@ nsHTMLFormElement::AddElement(nsGenericH
     if (oldDefaultSubmit && oldDefaultSubmit != mDefaultSubmitElement) {
       oldDefaultSubmit->UpdateState(aNotify);
     }
   }
 
   // If the element is subject to constraint validaton and is invalid, we need
   // to update our internal counter.
   if (aUpdateValidity) {
-    nsCOMPtr<nsIConstraintValidation> cvElmt =
-      do_QueryInterface(static_cast<nsGenericHTMLElement*>(aChild));
+    nsCOMPtr<nsIConstraintValidation> cvElmt = do_QueryObject(aChild);
     if (cvElmt &&
         cvElmt->IsCandidateForConstraintValidation() && !cvElmt->IsValid()) {
       UpdateValidity(PR_FALSE);
     }
   }
 
   // Notify the radio button it's been added to a group
   // This has to be done _after_ UpdateValidity() call to prevent the element
@@ -1296,18 +1295,17 @@ nsHTMLFormElement::RemoveElement(nsGener
     // being removed) because it's either being removed from the DOM or
     // changing attributes in a way that makes it responsible for sending its
     // own notifications.
   }
 
   // If the element was subject to constraint validaton and is invalid, we need
   // to update our internal counter.
   if (aUpdateValidity) {
-    nsCOMPtr<nsIConstraintValidation> cvElmt =
-      do_QueryInterface(static_cast<nsGenericHTMLElement*>(aChild));
+    nsCOMPtr<nsIConstraintValidation> cvElmt = do_QueryObject(aChild);
     if (cvElmt &&
         cvElmt->IsCandidateForConstraintValidation() && !cvElmt->IsValid()) {
       UpdateValidity(PR_TRUE);
     }
   }
 
   return rv;
 }
@@ -2345,18 +2343,17 @@ nsFormControlList::AddElementToTable(nsG
 
       // Determine the ordering between the new and old element.
       PRBool newFirst = nsContentUtils::PositionIsBefore(aChild, content);
 
       list->AppendElement(newFirst ? aChild : content);
       list->AppendElement(newFirst ? content : aChild);
 
 
-      nsCOMPtr<nsISupports> listSupports =
-        do_QueryInterface(static_cast<nsIDOMNodeList*>(list));
+      nsCOMPtr<nsISupports> listSupports = do_QueryObject(list);
 
       // Replace the element with the list.
       NS_ENSURE_TRUE(mNameLookupTable.Put(aName, listSupports),
                      NS_ERROR_FAILURE);
     } else {
       // There's already a list in the hash, add the child to the list
       nsCOMPtr<nsIDOMNodeList> nodeList(do_QueryInterface(supports));
       NS_ENSURE_TRUE(nodeList, NS_ERROR_FAILURE);
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -2250,18 +2250,17 @@ ImageContainer* nsHTMLMediaElement::GetI
     return mImageContainer;
 
   // If we have a print surface, this is just a static image so
   // no image container is required
   if (mPrintSurface)
     return nsnull;
 
   // Only video frames need an image container.
-  nsCOMPtr<nsIDOMHTMLVideoElement> video =
-    do_QueryInterface(static_cast<nsIContent*>(this));
+  nsCOMPtr<nsIDOMHTMLVideoElement> video = do_QueryObject(this);
   if (!video)
     return nsnull;
 
   nsRefPtr<LayerManager> manager =
     nsContentUtils::PersistentLayerManagerForDocument(GetOwnerDoc());
   if (!manager)
     return nsnull;
 
@@ -2278,17 +2277,17 @@ nsresult nsHTMLMediaElement::DispatchAud
 {
   // Auto manage the memory for the frame buffer. If we fail and return
   // an error, this ensures we free the memory in the frame buffer. Otherwise
   // we hand off ownership of the frame buffer to the audioavailable event,
   // which frees the memory when it's destroyed.
   nsAutoArrayPtr<float> frameBuffer(aFrameBuffer);
 
   nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(GetOwnerDoc());
-  nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(static_cast<nsIContent*>(this)));
+  nsCOMPtr<nsIDOMEventTarget> target(do_QueryObject(this));
   NS_ENSURE_TRUE(domDoc && target, NS_ERROR_INVALID_ARG);
 
   nsCOMPtr<nsIDOMEvent> event;
   nsresult rv = domDoc->CreateEvent(NS_LITERAL_STRING("MozAudioAvailableEvent"),
                                     getter_AddRefs(event));
   nsCOMPtr<nsIDOMNotifyAudioAvailableEvent> audioavailableEvent(do_QueryInterface(event));
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -2491,18 +2490,17 @@ void nsHTMLMediaElement::NotifyAddedSour
   if (mLoadWaitStatus == WAITING_FOR_SOURCE) {
     QueueLoadFromSourceTask();
   }
 }
 
 nsIContent* nsHTMLMediaElement::GetNextSource()
 {
   nsresult rv = NS_OK;
-  nsCOMPtr<nsIDOMNode> thisDomNode =
-    do_QueryInterface(static_cast<nsGenericElement*>(this));
+  nsCOMPtr<nsIDOMNode> thisDomNode = do_QueryObject(this);
 
   mSourceLoadCandidate = nsnull;
 
   if (!mSourcePointer) {
     // First time this has been run, create a selection to cover children.
     mSourcePointer = do_CreateInstance("@mozilla.org/content/range;1");
 
     rv = mSourcePointer->SelectNodeContents(thisDomNode);
--- a/content/media/test/manifest.js
+++ b/content/media/test/manifest.js
@@ -325,20 +325,23 @@ function MediaTestManager() {
   // to be one of, or have the same fields as, the g*Test arrays of tests. Uses
   // the user supplied 'startTest' function to initialize the test. This 
   // function must accept two arguments, the test entry from the 'tests' array,
   // and a token. Call MediaTestManager.started(token) if you start the test,
   // and MediaTestManager.finished(token) when the test finishes. You don't have
   // to start every test, but if you call started() you *must* call finish()
   // else you'll timeout. 
   this.runTests = function(tests, startTest) {
+    this.startTime = new Date();
+    SimpleTest.info("Started " + this.startTime + " (" + this.startTime.getTime()/1000 + "s)");
     this.testNum = 0;
     this.tests = tests;
     this.startTest = startTest;
     this.tokens = [];
+    this.isShutdown = false;
     // Always wait for explicit finish.
     SimpleTest.waitForExplicitFinish();
     this.nextTest();
   }
   
   // Registers that the test corresponding to 'token' has been started.
   // Don't call more than once per token.
   this.started = function(token) {
@@ -350,57 +353,62 @@ function MediaTestManager() {
   // run, otherwise it may start up the next run. It's ok to call multiple times
   // per token.
   this.finished = function(token) {
     var i = this.tokens.indexOf(token);
     if (i != -1) {
       // Remove the element from the list of running tests.
       this.tokens.splice(i, 1);
     }
-    if (this.tokens.length == 0) {
+    if (this.tokens.length < PARALLEL_TESTS) {
       this.nextTest();
     }
   }
   
   // Starts the next batch of tests, or finishes if they're all done.
   // Don't call this directly, call finished(token) when you're done.
   this.nextTest = function() {
     // Force a GC after every completed testcase. This ensures that any decoders
     // with live threads waiting for the GC are killed promptly, to free up the
     // thread stacks' address space.
     netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
     Components.utils.forceGC();
-    if (this.testNum == this.tests.length && !DEBUG_TEST_LOOP_FOREVER) {
-      if (this.onFinished) {
-        this.onFinished();
-      }
-      mediaTestCleanup();
-      SimpleTest.finish();
-      return;
-    }
+    
     while (this.testNum < this.tests.length && this.tokens.length < PARALLEL_TESTS) {
       var test = this.tests[this.testNum];
       var token = (test.name ? (test.name + "-"): "") + this.testNum;
       this.testNum++;
 
       if (DEBUG_TEST_LOOP_FOREVER && this.testNum == this.tests.length) {
         this.testNum = 0;
       }
       
       // Ensure we can play the resource type.
       if (test.type && !document.createElement('video').canPlayType(test.type))
         continue;
       
       // Do the init. This should start the test.
       this.startTest(test, token);
-      
     }
-    if (this.tokens.length == 0) {
-      // No tests were added, we must have tried everything, exit.
+
+    if (this.testNum == this.tests.length &&
+        !DEBUG_TEST_LOOP_FOREVER &&
+        this.tokens.length == 0 &&
+        !this.isShutdown)
+    {
+      this.isShutdown = true;
+      if (this.onFinished) {
+        this.onFinished();
+      }
+      mediaTestCleanup();
+      var end = new Date();
+      SimpleTest.info("Finished at " + end + " (" + (end.getTime() / 1000) + "s)");
+      SimpleTest.info("Running time: " + (end.getTime() - this.startTime.getTime())/1000 + "s");
       SimpleTest.finish();
+      return;
     }
   }
 }
 
 // Ensures we've got no active video or audio elements in the document, and
 // forces a GC to release the address space reserved by the decoders' threads'
 // stacks.
 function mediaTestCleanup() {
--- a/content/svg/content/src/nsSVGElement.cpp
+++ b/content/svg/content/src/nsSVGElement.cpp
@@ -2338,35 +2338,32 @@ nsSVGElement::RecompileScriptEventListen
 #ifdef MOZ_SMIL
 nsISMILAttr*
 nsSVGElement::GetAnimatedAttr(PRInt32 aNamespaceID, nsIAtom* aName)
 {
   if (aNamespaceID == kNameSpaceID_None) {
     // Transforms:
     nsCOMPtr<nsIDOMSVGAnimatedTransformList> transformList;
     if (aName == nsGkAtoms::transform) {
-      nsCOMPtr<nsIDOMSVGTransformable> transformable(
-              do_QueryInterface(static_cast<nsIContent*>(this)));
+      nsCOMPtr<nsIDOMSVGTransformable> transformable(do_QueryObject(this));
       if (!transformable)
         return nsnull;
       nsresult rv = transformable->GetTransform(getter_AddRefs(transformList));
       NS_ENSURE_SUCCESS(rv, nsnull);
     }
     if (aName == nsGkAtoms::gradientTransform) {
-      nsCOMPtr<nsIDOMSVGGradientElement> gradientElement(
-              do_QueryInterface(static_cast<nsIContent*>(this)));
+      nsCOMPtr<nsIDOMSVGGradientElement> gradientElement(do_QueryObject(this));
       if (!gradientElement)
         return nsnull;
 
       nsresult rv = gradientElement->GetGradientTransform(getter_AddRefs(transformList));
       NS_ENSURE_SUCCESS(rv, nsnull);
     }
     if (aName == nsGkAtoms::patternTransform) {
-      nsCOMPtr<nsIDOMSVGPatternElement> patternElement(
-              do_QueryInterface(static_cast<nsIContent*>(this)));
+      nsCOMPtr<nsIDOMSVGPatternElement> patternElement(do_QueryObject(this));
       if (!patternElement)
         return nsnull;
 
       nsresult rv = patternElement->GetPatternTransform(getter_AddRefs(transformList));
       NS_ENSURE_SUCCESS(rv, nsnull);
     }
     if (transformList) {
       nsSVGAnimatedTransformList* list
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -575,18 +575,17 @@ nsXULElement::IsFocusable(PRInt32 *aTabI
   PRBool shouldFocus = PR_FALSE;
 
 #ifdef XP_MACOSX
   // on Mac, mouse interactions only focus the element if it's a list
   if (aWithMouse && IsNonList(mNodeInfo))
     return PR_FALSE;
 #endif
 
-  nsCOMPtr<nsIDOMXULControlElement> xulControl = 
-    do_QueryInterface(static_cast<nsIContent*>(this));
+  nsCOMPtr<nsIDOMXULControlElement> xulControl = do_QueryObject(this);
   if (xulControl) {
     // a disabled element cannot be focused and is not part of the tab order
     PRBool disabled;
     xulControl->GetDisabled(&disabled);
     if (disabled) {
       if (aTabIndex)
         *aTabIndex = -1;
       return PR_FALSE;
@@ -953,17 +952,17 @@ nsXULElement::RemoveChildAt(PRUint32 aIn
     // anything else = index to re-set as current
     PRInt32 newCurrentIndex = -1;
 
     if (oldKid->NodeInfo()->Equals(nsGkAtoms::listitem, kNameSpaceID_XUL)) {
       // This is the nasty case. We have (potentially) a slew of selected items
       // and cells going away.
       // First, retrieve the tree.
       // Check first whether this element IS the tree
-      controlElement = do_QueryInterface(static_cast<nsIContent*>(this));
+      controlElement = do_QueryObject(this);
 
       // If it's not, look at our parent
       if (!controlElement)
         rv = GetParentTree(getter_AddRefs(controlElement));
 
       nsCOMPtr<nsIDOMElement> oldKidElem = do_QueryInterface(oldKid);
       if (controlElement && oldKidElem) {
         // Iterate over all of the items and find out if they are contained inside
@@ -2052,17 +2051,17 @@ nsXULElement::GetParentTree(nsIDOMXULMul
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULElement::Focus()
 {
     nsIFocusManager* fm = nsFocusManager::GetFocusManager();
-    nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(static_cast<nsIContent*>(this));
+    nsCOMPtr<nsIDOMElement> elem = do_QueryObject(this);
     return fm ? fm->SetFocus(this, 0) : NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULElement::Blur()
 {
     if (!ShouldBlur(this))
       return NS_OK;
--- a/docshell/base/nsDSURIContentListener.cpp
+++ b/docshell/base/nsDSURIContentListener.cpp
@@ -374,17 +374,17 @@ bool nsDSURIContentListener::CheckFrameO
             // If the value of the header is DENY, then the document
             // should never be permitted to load as a subdocument.
             NS_ASSERTION(xfoHeaderValue.LowerCaseEqualsLiteral("deny"),
                          "How did we get here with some random header value?");
         }
 
         // cancel the load and display about:blank
         httpChannel->Cancel(NS_BINDING_ABORTED);
-        nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(static_cast<nsIDocShell*>(mDocShell)));
+        nsCOMPtr<nsIWebNavigation> webNav(do_QueryObject(mDocShell));
         if (webNav) {
             webNav->LoadURI(NS_LITERAL_STRING("about:blank").get(),
                             0, nsnull, nsnull, nsnull);
         }
         return false;
     }
 
     return true;
--- a/dom/base/nsDOMMemoryReporter.cpp
+++ b/dom/base/nsDOMMemoryReporter.cpp
@@ -98,13 +98,15 @@ GetWindowsMemoryUsage(const PRUint64& aI
   return PL_DHASH_NEXT;
 }
 
 NS_IMETHODIMP
 nsDOMMemoryReporter::GetAmount(PRInt64* aAmount) {
   *aAmount = 0;
 
   nsGlobalWindow::WindowByIdTable* windows = nsGlobalWindow::GetWindowsTable();
+  NS_ENSURE_TRUE(windows, NS_OK);
+
   windows->Enumerate(GetWindowsMemoryUsage, aAmount);
 
   return NS_OK;
 }
 
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1096,18 +1096,17 @@ nsGlobalWindow::MaybeForgiveSpamCount()
   }
 }
 
 void
 nsGlobalWindow::CleanUp(PRBool aIgnoreModalDialog)
 {
   if (IsOuterWindow() && !aIgnoreModalDialog) {
     nsGlobalWindow* inner = GetCurrentInnerWindowInternal();
-    nsCOMPtr<nsIDOMModalContentWindow>
-      dlg(do_QueryInterface(static_cast<nsPIDOMWindow*>(inner)));
+    nsCOMPtr<nsIDOMModalContentWindow> dlg(do_QueryObject(inner));
     if (dlg) {
       // The window we're trying to clean up is the outer window of a
       // modal dialog.  Defer cleanup until the window closes, and let
       // ShowModalDialog take care of calling CleanUp.
       mCallCleanUpAfterModalDialogCloses = PR_TRUE;
       return;
     }
   }
@@ -9774,18 +9773,17 @@ nsGlobalWindow::BuildURIfromBase(const c
     *aCXused = nsnull;
 
   // get JSContext
   NS_ASSERTION(scx, "opening window missing its context");
   NS_ASSERTION(mDocument, "opening window missing its document");
   if (!scx || !mDocument)
     return NS_ERROR_FAILURE;
 
-  nsCOMPtr<nsIDOMChromeWindow> chrome_win =
-    do_QueryInterface(static_cast<nsIDOMWindow *>(this));
+  nsCOMPtr<nsIDOMChromeWindow> chrome_win = do_QueryObject(this);
 
   if (nsContentUtils::IsCallerChrome() && !chrome_win) {
     // If open() is called from chrome on a non-chrome window, we'll
     // use the context from the window on which open() is being called
     // to prevent giving chrome priveleges to new windows opened in
     // such a way. This also makes us get the appropriate base URI for
     // the below URI resolution code.
 
--- a/dom/indexedDB/AsyncConnectionHelper.cpp
+++ b/dom/indexedDB/AsyncConnectionHelper.cpp
@@ -285,18 +285,17 @@ AsyncConnectionHelper::Run()
 
   if (!mStartTime.IsNull()) {
     nsCOMPtr<mozIStorageProgressHandler> handler;
     rv = connection->RemoveProgressHandler(getter_AddRefs(handler));
     NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "RemoveProgressHandler failed!");
 #ifdef DEBUG
     if (NS_SUCCEEDED(rv)) {
       nsCOMPtr<nsISupports> handlerSupports(do_QueryInterface(handler));
-      nsCOMPtr<nsISupports> thisSupports =
-        do_QueryInterface(static_cast<nsIRunnable*>(this));
+      nsCOMPtr<nsISupports> thisSupports = do_QueryObject(this);
       NS_ASSERTION(thisSupports == handlerSupports, "Mismatch!");
     }
 #endif
     mStartTime = TimeStamp();
   }
 
   return NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL);
 }
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -682,18 +682,20 @@ ContentChild::RecvGeolocationUpdate(cons
   gs->Update(position);
   return true;
 }
 
 bool
 ContentChild::RecvAddPermission(const IPC::Permission& permission)
 {
 #if MOZ_PERMISSIONS
-  nsRefPtr<nsPermissionManager> permissionManager =
-    nsPermissionManager::GetSingleton();
+  nsCOMPtr<nsIPermissionManager> permissionManagerIface =
+      do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
+  nsPermissionManager* permissionManager =
+      static_cast<nsPermissionManager*>(permissionManagerIface.get());
   NS_ABORT_IF_FALSE(permissionManager, 
                    "We have no permissionManager in the Content process !");
 
   permissionManager->AddInternal(nsCString(permission.host),
                                  nsCString(permission.type),
                                  permission.capability,
                                  0,
                                  permission.expireType,
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -264,23 +264,38 @@ ContentParent::OnChannelConnected(int32 
                 setpriority(PRIO_PROCESS, pid, getpriority(PRIO_PROCESS, pid) + nice);
             }
         }
 #endif
     }
 }
 
 namespace {
+
 void
 DelayedDeleteSubprocess(GeckoChildProcessHost* aSubprocess)
 {
     XRE_GetIOMessageLoop()
         ->PostTask(FROM_HERE,
                    new DeleteTask<GeckoChildProcessHost>(aSubprocess));
 }
+
+// This runnable only exists to delegate ownership of the
+// ContentParent to this runnable, until it's deleted by the event
+// system.
+struct DelayedDeleteContentParentTask : public nsRunnable
+{
+    DelayedDeleteContentParentTask(ContentParent* aObj) : mObj(aObj) { }
+
+    // No-op
+    NS_IMETHODIMP Run() { return NS_OK; }
+
+    nsRefPtr<ContentParent> mObj;
+};
+
 }
 
 void
 ContentParent::ActorDestroy(ActorDestroyReason why)
 {
     nsCOMPtr<nsIThreadObserver>
         kungFuDeathGrip(static_cast<nsIThreadObserver*>(this));
     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
@@ -361,16 +376,25 @@ ContentParent::ActorDestroy(ActorDestroy
             obs->NotifyObservers((nsIPropertyBag2*) props, "ipc:content-shutdown", nsnull);
         }
     }
 
     MessageLoop::current()->
         PostTask(FROM_HERE,
                  NewRunnableFunction(DelayedDeleteSubprocess, mSubprocess));
     mSubprocess = NULL;
+
+    // IPDL rules require actors to live on past ActorDestroy, but it
+    // may be that the kungFuDeathGrip above is the last reference to
+    // |this|.  If so, when we go out of scope here, we're deleted and
+    // all hell breaks loose.
+    //
+    // This runnable ensures that a reference to |this| lives on at
+    // least until after the current task finishes running.
+    NS_DispatchToCurrentThread(new DelayedDeleteContentParentTask(this));
 }
 
 TabParent*
 ContentParent::CreateTab(PRUint32 aChromeFlags)
 {
   return static_cast<TabParent*>(SendPBrowserConstructor(aChromeFlags));
 }
 
@@ -450,18 +474,20 @@ ContentParent::EnsurePrefService()
                      "We lost prefService in the Chrome process !");
     }
 }
 
 bool
 ContentParent::RecvReadPermissions(InfallibleTArray<IPC::Permission>* aPermissions)
 {
 #ifdef MOZ_PERMISSIONS
-    nsRefPtr<nsPermissionManager> permissionManager =
-        nsPermissionManager::GetSingleton();
+    nsCOMPtr<nsIPermissionManager> permissionManagerIface =
+        do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
+    nsPermissionManager* permissionManager =
+        static_cast<nsPermissionManager*>(permissionManagerIface.get());
     NS_ABORT_IF_FALSE(permissionManager,
                  "We have no permissionManager in the Chrome process !");
 
     nsCOMPtr<nsISimpleEnumerator> enumerator;
     nsresult rv = permissionManager->GetEnumerator(getter_AddRefs(enumerator));
     NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv), "Could not get enumerator!");
     while(1) {
         PRBool hasMore;
--- a/dom/plugins/base/nsPluginInstanceOwner.h
+++ b/dom/plugins/base/nsPluginInstanceOwner.h
@@ -64,17 +64,17 @@
 #endif
 
 #ifdef XP_MACOSX
 #include "nsCoreAnimationSupport.h"
 #include <ApplicationServices/ApplicationServices.h>
 #endif
 
 class nsIInputStream;
-class nsIntRect;
+struct nsIntRect;
 class nsPluginDOMContextMenuListener;
 class nsObjectFrame;
 class nsDisplayListBuilder;
 
 #ifdef MOZ_X11
 class gfxXlibSurface;
 #endif
 
--- a/editor/libeditor/base/nsEditorEventListener.cpp
+++ b/editor/libeditor/base/nsEditorEventListener.cpp
@@ -403,17 +403,17 @@ nsEditorEventListener::MouseClick(nsIDOM
 
       // If the ctrl key is pressed, we'll do paste as quotation.
       // Would've used the alt key, but the kde wmgr treats alt-middle specially. 
       PRBool ctrlKey = PR_FALSE;
       mouseEvent->GetCtrlKey(&ctrlKey);
 
       nsCOMPtr<nsIEditorMailSupport> mailEditor;
       if (ctrlKey)
-        mailEditor = do_QueryInterface(static_cast<nsIEditor*>(mEditor));
+        mailEditor = do_QueryObject(mEditor);
 
       PRInt32 clipboard;
 
 #if defined(XP_OS2) || defined(XP_WIN32)
       clipboard = nsIClipboard::kGlobalClipboard;
 #else
       clipboard = nsIClipboard::kSelectionClipboard;
 #endif
--- a/editor/libeditor/html/nsHTMLEditorEventListener.cpp
+++ b/editor/libeditor/html/nsHTMLEditorEventListener.cpp
@@ -62,20 +62,18 @@
  * nsHTMLEditorEventListener implementation
  *
  */
 
 #ifdef DEBUG
 nsresult
 nsHTMLEditorEventListener::Connect(nsEditor* aEditor)
 {
-  nsCOMPtr<nsIHTMLEditor> htmlEditor =
-    do_QueryInterface(static_cast<nsIEditor*>(aEditor));
-  nsCOMPtr<nsIHTMLInlineTableEditor> htmlInlineTableEditor =
-    do_QueryInterface(static_cast<nsIEditor*>(aEditor));
+  nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryObject(aEditor);
+  nsCOMPtr<nsIHTMLInlineTableEditor> htmlInlineTableEditor = do_QueryObject(aEditor);
   NS_PRECONDITION(htmlEditor && htmlInlineTableEditor,
                   "Set nsHTMLEditor or its sub class");
   return nsEditorEventListener::Connect(aEditor);
 }
 #endif
 
 nsHTMLEditor*
 nsHTMLEditorEventListener::GetHTMLEditor()
--- a/extensions/cookie/nsCookiePermission.cpp
+++ b/extensions/cookie/nsCookiePermission.cpp
@@ -362,26 +362,28 @@ nsCookiePermission::CanSetCookie(nsIURI 
       if (!foundCookie && !*aIsSession && delta <= 0) {
         // the cookie has already expired. accept it, and let the backend figure
         // out it's expired, so that we get correct logging & notifications.
         *aResult = PR_TRUE;
         return rv;
       }
 
       PRBool rememberDecision = PR_FALSE;
+      PRInt32 dialogRes = nsICookiePromptService::DENY_COOKIE;
       rv = cookiePromptService->CookieDialog(parent, aCookie, hostPort, 
                                              countFromHost, foundCookie,
-                                             &rememberDecision, aResult);
+                                             &rememberDecision, &dialogRes);
       if (NS_FAILED(rv)) return rv;
-      
-      if (*aResult == nsICookiePromptService::ACCEPT_SESSION_COOKIE)
+
+      *aResult = !!dialogRes;
+      if (dialogRes == nsICookiePromptService::ACCEPT_SESSION_COOKIE)
         *aIsSession = PR_TRUE;
 
       if (rememberDecision) {
-        switch (*aResult) {
+        switch (dialogRes) {
           case nsICookiePromptService::DENY_COOKIE:
             mPermMgr->Add(aURI, kPermissionType, (PRUint32) nsIPermissionManager::DENY_ACTION,
                           nsIPermissionManager::EXPIRE_NEVER, 0);
             break;
           case nsICookiePromptService::ACCEPT_COOKIE:
             mPermMgr->Add(aURI, kPermissionType, (PRUint32) nsIPermissionManager::ALLOW_ACTION,
                           nsIPermissionManager::EXPIRE_NEVER, 0);
             break;
--- a/extensions/cookie/nsCookiePromptService.cpp
+++ b/extensions/cookie/nsCookiePromptService.cpp
@@ -109,17 +109,17 @@ nsCookiePromptService::CookieDialog(nsID
   // avoids unwanted tab switches (see bug 405239).
   rv = wwatcher->OpenWindow(parent, "chrome://cookie/content/cookieAcceptDialog.xul", "_blank",
                             "centerscreen,chrome,modal,titlebar", arguments,
                             getter_AddRefs(dialog));
 
   if (NS_FAILED(rv)) return rv;
 
   // get back output parameters
-  PRBool tempValue;
+  PRInt32 tempValue;
   block->GetInt(nsICookieAcceptDialog::ACCEPT_COOKIE, &tempValue);
   *aAccept = tempValue;
   
   // GetInt returns a PRInt32; we need to sanitize it into PRBool
   block->GetInt(nsICookieAcceptDialog::REMEMBER_DECISION, &tempValue);
   *aRememberDecision = (tempValue == 1);
 
   return rv;
--- a/extensions/cookie/nsPermissionManager.cpp
+++ b/extensions/cookie/nsPermissionManager.cpp
@@ -154,29 +154,23 @@ NS_IMPL_ISUPPORTS3(nsPermissionManager, 
 nsPermissionManager::nsPermissionManager()
  : mLargestID(0)
 {
 }
 
 nsPermissionManager::~nsPermissionManager()
 {
   RemoveAllFromMemory();
+  gPermissionManager = nsnull;
 }
 
 // static
 nsIPermissionManager*
 nsPermissionManager::GetXPCOMSingleton()
 {
-  return GetSingleton().get();
-}
-
-// static
-already_AddRefed<nsPermissionManager>
-nsPermissionManager::GetSingleton()
-{
   if (gPermissionManager) {
     NS_ADDREF(gPermissionManager);
     return gPermissionManager;
   }
 
   // Create a new singleton nsPermissionManager.
   // We AddRef only once since XPCOM has rules about the ordering of module
   // teardowns - by the time our module destructor is called, it's too late to
@@ -793,17 +787,17 @@ NS_IMETHODIMP nsPermissionManager::Obser
     // The profile is about to change,
     // or is going away because the application is shutting down.
     if (!nsCRT::strcmp(someData, NS_LITERAL_STRING("shutdown-cleanse").get())) {
       // clear the permissions file
       RemoveAllInternal();
     } else {
       RemoveAllFromMemory();
     }
-  }  
+  }
   else if (!nsCRT::strcmp(aTopic, "profile-do-change")) {
     // the profile has already changed; init the db from the new location
     InitDB(PR_FALSE);
   }
 
   return NS_OK;
 }
 
--- a/extensions/cookie/nsPermissionManager.h
+++ b/extensions/cookie/nsPermissionManager.h
@@ -163,17 +163,16 @@ public:
   // nsISupports
   NS_DECL_ISUPPORTS
   NS_DECL_NSIPERMISSIONMANAGER
   NS_DECL_NSIOBSERVER
 
   nsPermissionManager();
   virtual ~nsPermissionManager();
   static nsIPermissionManager* GetXPCOMSingleton();
-  static already_AddRefed<nsPermissionManager> GetSingleton();
   nsresult Init();
 
   // enums for AddInternal()
   enum OperationType {
     eOperationNone,
     eOperationAdding,
     eOperationRemoving,
     eOperationChanging
--- a/gfx/angle/CONTRIBUTORS
+++ b/gfx/angle/CONTRIBUTORS
@@ -1,38 +1,42 @@
-# This is the official list of people who can contribute
-# (and who have contributed) code to the ANGLE project
-# repository.
-# The AUTHORS file lists the copyright holders; this file
-# lists people.  For example, Google employees are listed here
-# but not in AUTHORS, because Google holds the copyright.
-#
-
-TransGaming Inc.
- Nicolas Capens
- Daniel Koch
- Andrew Lewycky
- Gavriel State
- Shannon Woods
-
-Google Inc.
- Brent Austin
- John Bauman
- Henry Bridge
- Nat Duca
- Vangelis Kokkevis
- Alastair Patrick
- Alok Priyadarshi
- Kenneth Russell
- Ben Vanik
- Adrienne Walker
-
-Mozilla Corp.
- Vladimir Vukicevic
- Benoit Jacob
-
-Apple Inc.
- David Kilzer
-
-Aitor Moreno <aitormoreno at gmail.com>
-Jim Hauxwell <james at dattrax.co.uk>
-ddefrostt
-timeless
+# This is the official list of people who can contribute
+# (and who have contributed) code to the ANGLE project
+# repository.
+# The AUTHORS file lists the copyright holders; this file
+# lists people.  For example, Google employees are listed here
+# but not in AUTHORS, because Google holds the copyright.
+#
+
+TransGaming Inc.
+ Nicolas Capens
+ Daniel Koch
+ Andrew Lewycky
+ Gavriel State
+ Shannon Woods
+
+Google Inc.
+ Brent Austin
+ John Bauman
+ Henry Bridge
+ Nat Duca
+ Vangelis Kokkevis
+ Zhenyao Mo
+ Daniel Nicoara
+ Alastair Patrick
+ Alok Priyadarshi
+ Kenneth Russell
+ Ben Vanik
+ Adrienne Walker
+
+Mozilla Corp.
+ Benoit Jacob
+ Makoto Kato
+ Vladimir Vukicevic
+
+Apple Inc.
+ David Kilzer
+
+Aitor Moreno <aitormoreno at gmail.com>
+Jim Hauxwell <james at dattrax.co.uk>
+ddefrostt
+timeless
+Yore Apex
--- a/gfx/angle/Makefile.in
+++ b/gfx/angle/Makefile.in
@@ -72,37 +72,41 @@ CPPSRCS = \
         MozAngleLink.cpp \
         parseConst.cpp \
         ParseHelper.cpp \
         PoolAlloc.cpp \
         QualifierAlive.cpp \
         RemoveTree.cpp \
         ShaderLang.cpp \
         SymbolTable.cpp \
-	VariableInfo.cpp \
-	compilerdebug.cpp \
-	ossource_nspr.cpp \
-	util.cpp \
-	ValidateLimitations.cpp \
-	ForLoopUnroll.cpp \
-	MapLongVariableNames.cpp \
-	$(NULL)
+        VariableInfo.cpp \
+        compilerdebug.cpp \
+        ossource_nspr.cpp \
+        util.cpp \
+        ValidateLimitations.cpp \
+        ForLoopUnroll.cpp \
+        MapLongVariableNames.cpp \
+        BuiltInFunctionEmulator.cpp \
+        $(NULL)
 
 # flex/yacc generated files
 CPPSRCS += \
-	glslang_lex.cpp \
-	glslang_tab.cpp \
-	$(NULL)
+        glslang_lex.cpp \
+        glslang_tab.cpp \
+        $(NULL)
 
 # GLSL translator backend
 CPPSRCS += \
-	CodeGenGLSL.cpp \
-	OutputGLSL.cpp \
-	TranslatorGLSL.cpp \
-	VersionGLSL.cpp \
+        CodeGenGLSL.cpp \
+        OutputGLSL.cpp \
+        TranslatorGLSL.cpp \
+        VersionGLSL.cpp \
+        OutputESSL.cpp \
+        OutputGLSLBase.cpp \
+        TranslatorESSL.cpp \
 	$(NULL)
 
 # Currently, only one or the other
 # can be selected.
 
 ## HLSL translator backend
 ##CPPSRCS += \
 ##	CodeGenHLSL.cpp \
--- a/gfx/angle/README.mozilla
+++ b/gfx/angle/README.mozilla
@@ -1,27 +1,19 @@
 This is the ANGLE project, from http://code.google.com/p/angleproject/.
 
-Current revision: r686
+Current revision: r740
 
 == Applied local patches ==
 
 In this order:
   angle-nspr-misc.patch - don't bother with ANGLE_OS detection with NSPR
   angle-renaming.patch - rename debug.h to compilerdebug.h to avoid conflict in our makefiles
   angle-intrinsic-msvc2005.patch - work around a MSVC 2005 compile error
-  angle-amap-arev-fix.patch - plain bug fix, this is ANGLE r699
-  angle-r702.patch - this is ANGLE r702
   angle-limit-identifiers-to-250-chars.patch - see bug 675625
-  angle-r712.patch - this is ANGLE r712
-  angle-win64.patch - Win64 support. This is ANGLE r697
-  angle-r707.patch - this is ANGLE r707 for Win64 bug fix
-  angle-r719.patch - this is ANGLE r719
-  angle-r711.patch - this is ANGLE r711
-  fix-angle-surface-assert.patch - this is ANGLE r739
 
 In addition to these patches, the Makefile.in files are ours, they're not present in upsteam ANGLE.
 
 == How to update this ANGLE copy ==
 
 1. Unapply patches
 2. Apply diff with new ANGLE version
 3. Reapply patches.
deleted file mode 100644
--- a/gfx/angle/angle-amap-arev-fix.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-# HG changeset patch
-# Parent c88f8e8921fb6399cf95b5899d2acc60951dddd1
-Bug 665934 - fix bug: arev was meant instead of amap - r=upstream
-
-This patch has been taken in ANGLE upstream as r699.
-
-diff --git a/gfx/angle/src/compiler/preprocessor/atom.c b/gfx/angle/src/compiler/preprocessor/atom.c
---- a/gfx/angle/src/compiler/preprocessor/atom.c
-+++ b/gfx/angle/src/compiler/preprocessor/atom.c
-@@ -330,17 +330,17 @@ static int GrowAtomTable(AtomTable *atab
-             newrev = malloc(sizeof(int)*size);
-             atable->size = 0;
-         }
-         if (!newmap || !newrev) {
-             /* failed to grow -- error */
-             if (newmap)
-                 atable->amap = newmap;
-             if (newrev)
--                atable->amap = newrev;
-+                atable->arev = newrev;
-             return -1;
-         }
-         memset(&newmap[atable->size], 0, (size - atable->size) * sizeof(int));
-         memset(&newrev[atable->size], 0, (size - atable->size) * sizeof(int));
-         atable->amap = newmap;
-         atable->arev = newrev;
-         atable->size = size;
-     }
deleted file mode 100644
--- a/gfx/angle/angle-r702.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-# HG changeset patch
-# Parent b410077eaab7f6f851ebefa26fd9e1df938026bb
-
-diff --git a/gfx/angle/src/libGLESv2/VertexDataManager.cpp b/gfx/angle/src/libGLESv2/VertexDataManager.cpp
---- a/gfx/angle/src/libGLESv2/VertexDataManager.cpp
-+++ b/gfx/angle/src/libGLESv2/VertexDataManager.cpp
-@@ -134,19 +134,33 @@ GLenum VertexDataManager::prepareVertexD
-                 if (staticBuffer->size() == 0)
-                 {
-                     int totalCount = buffer->size() / attribs[i].stride();
-                     staticBuffer->addRequiredSpace(spaceRequired(attribs[i], totalCount));
-                 }
-                 else if (staticBuffer->lookupAttribute(attribs[i]) == -1)
-                 {
-                     // This static buffer doesn't have matching attributes, so fall back to using the streaming buffer
--                    mStreamingBuffer->addRequiredSpaceFor(staticBuffer);
-                     buffer->invalidateStaticData();
- 
-+                    // Add the space of all previous attributes belonging to the invalidated static buffer to the streaming buffer
-+                    for (int previous = 0; previous < i; previous++)
-+                    {
-+                        if (translated[previous].active && attribs[previous].mArrayEnabled)
-+                        {
-+                            Buffer *previousBuffer = attribs[previous].mBoundBuffer.get();
-+                            StaticVertexBuffer *previousStaticBuffer = previousBuffer ? previousBuffer->getStaticVertexBuffer() : NULL;
-+
-+                            if (staticBuffer == previousStaticBuffer)
-+                            {
-+                                mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[previous], count));
-+                            }
-+                        }
-+                    }
-+
-                     mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count));
-                 }    
-             }
-             else
-             {
-                 mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count));
-             }
-         }
-@@ -578,21 +592,16 @@ ArrayVertexBuffer::~ArrayVertexBuffer()
- {
- }
- 
- void ArrayVertexBuffer::addRequiredSpace(UINT requiredSpace)
- {
-     mRequiredSpace += requiredSpace;
- }
- 
--void ArrayVertexBuffer::addRequiredSpaceFor(ArrayVertexBuffer *buffer)
--{
--    mRequiredSpace += buffer->mRequiredSpace;
--}
--
- StreamingVertexBuffer::StreamingVertexBuffer(IDirect3DDevice9 *device, std::size_t initialSize) : ArrayVertexBuffer(device, initialSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY)
- {
- }
- 
- StreamingVertexBuffer::~StreamingVertexBuffer()
- {
- }
- 
-diff --git a/gfx/angle/src/libGLESv2/VertexDataManager.h b/gfx/angle/src/libGLESv2/VertexDataManager.h
---- a/gfx/angle/src/libGLESv2/VertexDataManager.h
-+++ b/gfx/angle/src/libGLESv2/VertexDataManager.h
-@@ -62,17 +62,16 @@ class ArrayVertexBuffer : public VertexB
-   public:
-     ArrayVertexBuffer(IDirect3DDevice9 *device, UINT size, DWORD usageFlags);
-     ~ArrayVertexBuffer();
- 
-     UINT size() const { return mBufferSize; }
-     virtual void *map(const VertexAttribute &attribute, UINT requiredSpace, UINT *streamOffset) = 0;
-     virtual void reserveRequiredSpace() = 0;
-     void addRequiredSpace(UINT requiredSpace);
--    void addRequiredSpaceFor(ArrayVertexBuffer *buffer);
- 
-   protected:
-     UINT mBufferSize;
-     UINT mWritePosition;
-     UINT mRequiredSpace;
- };
- 
- class StreamingVertexBuffer : public ArrayVertexBuffer
deleted file mode 100644
--- a/gfx/angle/angle-r707.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-diff --git a/gfx/angle/src/libGLESv2/VertexDataManager.cpp b/gfx/angle/src/libGLESv2/VertexDataManager.cpp
---- a/gfx/angle/src/libGLESv2/VertexDataManager.cpp
-+++ b/gfx/angle/src/libGLESv2/VertexDataManager.cpp
-@@ -714,17 +714,17 @@ void StaticVertexBuffer::reserveRequired
-     {
-         // Already allocated
-     }
-     else UNREACHABLE();   // Static vertex buffers can't be resized
- 
-     mRequiredSpace = 0;
- }
- 
--UINT StaticVertexBuffer::lookupAttribute(const VertexAttribute &attribute)
-+std::size_t StaticVertexBuffer::lookupAttribute(const VertexAttribute &attribute)
- {
-     for (unsigned int element = 0; element < mCache.size(); element++)
-     {
-         if (mCache[element].type == attribute.mType &&  mCache[element].size == attribute.mSize && mCache[element].normalized == attribute.mNormalized)
-         {
-             if (mCache[element].attributeOffset == attribute.mOffset % attribute.stride())
-             {
-                 return mCache[element].streamOffset;
-diff --git a/gfx/angle/src/libGLESv2/VertexDataManager.h b/gfx/angle/src/libGLESv2/VertexDataManager.h
---- a/gfx/angle/src/libGLESv2/VertexDataManager.h
-+++ b/gfx/angle/src/libGLESv2/VertexDataManager.h
-@@ -88,17 +88,17 @@ class StaticVertexBuffer : public ArrayV
- {
-   public:
-     explicit StaticVertexBuffer(IDirect3DDevice9 *device);
-     ~StaticVertexBuffer();
- 
-     void *map(const VertexAttribute &attribute, std::size_t requiredSpace, std::size_t *streamOffset);
-     void reserveRequiredSpace();
- 
--    UINT lookupAttribute(const VertexAttribute &attribute);   // Returns the offset into the vertex buffer, or -1 if not found
-+    std::size_t lookupAttribute(const VertexAttribute &attribute);   // Returns the offset into the vertex buffer, or -1 if not found
- 
-   private:
-     struct VertexElement
-     {
-         GLenum type;
-         GLint size;
-         bool normalized;
-         int attributeOffset;
- 
deleted file mode 100644
--- a/gfx/angle/angle-r712.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-# HG changeset patch
-# Parent 88a5c8710f5cffd568bc21226118cb567850ce28
-diff --git a/gfx/angle/src/libGLESv2/VertexDataManager.cpp b/gfx/angle/src/libGLESv2/VertexDataManager.cpp
---- a/gfx/angle/src/libGLESv2/VertexDataManager.cpp
-+++ b/gfx/angle/src/libGLESv2/VertexDataManager.cpp
-@@ -134,34 +134,34 @@ GLenum VertexDataManager::prepareVertexD
-                 if (staticBuffer->size() == 0)
-                 {
-                     int totalCount = buffer->size() / attribs[i].stride();
-                     staticBuffer->addRequiredSpace(spaceRequired(attribs[i], totalCount));
-                 }
-                 else if (staticBuffer->lookupAttribute(attribs[i]) == -1)
-                 {
-                     // This static buffer doesn't have matching attributes, so fall back to using the streaming buffer
--                    buffer->invalidateStaticData();
--
-                     // Add the space of all previous attributes belonging to the invalidated static buffer to the streaming buffer
-                     for (int previous = 0; previous < i; previous++)
-                     {
-                         if (translated[previous].active && attribs[previous].mArrayEnabled)
-                         {
-                             Buffer *previousBuffer = attribs[previous].mBoundBuffer.get();
-                             StaticVertexBuffer *previousStaticBuffer = previousBuffer ? previousBuffer->getStaticVertexBuffer() : NULL;
- 
-                             if (staticBuffer == previousStaticBuffer)
-                             {
-                                 mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[previous], count));
-                             }
-                         }
-                     }
- 
-                     mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count));
-+
-+                    buffer->invalidateStaticData();
-                 }    
-             }
-             else
-             {
-                 mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count));
-             }
-         }
-     }
--- a/gfx/angle/angle-renaming-debug.patch
+++ b/gfx/angle/angle-renaming-debug.patch
@@ -1,67 +1,44 @@
 # HG changeset patch
-# Parent a0dd1332c0e6ebaf429f9a3732b8901f9e46cde0
+# Parent 96359f46b01fdb37e791f564495e8b2755a05233
+
 diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
 --- a/gfx/angle/Makefile.in
 +++ b/gfx/angle/Makefile.in
-@@ -72,17 +72,17 @@ CPPSRCS = \
+@@ -73,17 +73,17 @@ CPPSRCS = \
          parseConst.cpp \
          ParseHelper.cpp \
          PoolAlloc.cpp \
          QualifierAlive.cpp \
          RemoveTree.cpp \
          ShaderLang.cpp \
          SymbolTable.cpp \
- 	VariableInfo.cpp \
--	debug.cpp \
-+	compilerdebug.cpp \
- 	ossource_nspr.cpp \
- 	util.cpp \
- 	ValidateLimitations.cpp \
- 	ForLoopUnroll.cpp \
- 	MapLongVariableNames.cpp \
- 	$(NULL)
+         VariableInfo.cpp \
+-        debug.cpp \
++        compilerdebug.cpp \
+         ossource_nspr.cpp \
+         util.cpp \
+         ValidateLimitations.cpp \
+         ForLoopUnroll.cpp \
+         MapLongVariableNames.cpp \
+         BuiltInFunctionEmulator.cpp \
+         $(NULL)
  
- # flex/yacc generated files
-diff --git a/gfx/angle/src/build_angle.gyp b/gfx/angle/src/build_angle.gyp
---- a/gfx/angle/src/build_angle.gyp
-+++ b/gfx/angle/src/build_angle.gyp
-@@ -17,18 +17,18 @@
-         '.',
-         '../include',
-       ],
-       'sources': [
-         'compiler/BaseTypes.h',
-         'compiler/Common.h',
-         'compiler/Compiler.cpp',
-         'compiler/ConstantUnion.h',
--        'compiler/debug.cpp',
--        'compiler/debug.h',
-+        'compiler/compilerdebug.cpp',
-+        'compiler/compilerdebug.h',
-         'compiler/glslang.h',
-         'compiler/glslang_lex.cpp',
-         'compiler/glslang_tab.cpp',
-         'compiler/glslang_tab.h',
-         'compiler/InfoSink.cpp',
-         'compiler/InfoSink.h',
-         'compiler/Initialize.cpp',
-         'compiler/Initialize.h',
-diff --git a/gfx/angle/src/compiler/OutputGLSL.cpp b/gfx/angle/src/compiler/OutputGLSL.cpp
---- a/gfx/angle/src/compiler/OutputGLSL.cpp
-+++ b/gfx/angle/src/compiler/OutputGLSL.cpp
+diff --git a/gfx/angle/src/compiler/OutputGLSLBase.cpp b/gfx/angle/src/compiler/OutputGLSLBase.cpp
+--- a/gfx/angle/src/compiler/OutputGLSLBase.cpp
++++ b/gfx/angle/src/compiler/OutputGLSLBase.cpp
 @@ -1,16 +1,16 @@
  //
  // Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  //
  
- #include "compiler/OutputGLSL.h"
+ #include "compiler/OutputGLSLBase.h"
 -#include "compiler/debug.h"
 +#include "compiler/compilerdebug.h"
  
  namespace
  {
  TString getTypeName(const TType& type)
  {
      TInfoSinkBase out;
@@ -152,17 +129,17 @@ diff --git a/gfx/angle/src/compiler/comp
  
  #include <assert.h>
  
  #ifdef _DEBUG
  #define TRACE_ENABLED  // define to enable debug message tracing
 diff --git a/gfx/angle/src/compiler/osinclude.h b/gfx/angle/src/compiler/osinclude.h
 --- a/gfx/angle/src/compiler/osinclude.h
 +++ b/gfx/angle/src/compiler/osinclude.h
-@@ -30,17 +30,17 @@
+@@ -32,17 +32,17 @@
  #include <windows.h>
  #elif defined(ANGLE_OS_POSIX)
  #include <pthread.h>
  #include <semaphore.h>
  #include <errno.h>
  #endif  // ANGLE_USE_NSPR
  
  
deleted file mode 100644
--- a/gfx/angle/angle-win64.patch
+++ /dev/null
@@ -1,235 +0,0 @@
-diff --git a/gfx/angle/src/libEGL/Surface.cpp b/gfx/angle/src/libEGL/Surface.cpp
---- a/gfx/angle/src/libEGL/Surface.cpp
-+++ b/gfx/angle/src/libEGL/Surface.cpp
-@@ -285,17 +285,17 @@ void Surface::subclassWindow()
-     DWORD processId;
-     DWORD threadId = GetWindowThreadProcessId(mWindow, &processId);
-     if (processId != GetCurrentProcessId() || threadId != GetCurrentThreadId())
-     {
-         return;
-     }
- 
-     SetLastError(0);
--    LONG oldWndProc = SetWindowLong(mWindow, GWL_WNDPROC, reinterpret_cast<LONG>(SurfaceWindowProc));
-+    LONG_PTR oldWndProc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
-     if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS)
-     {
-         mWindowSubclassed = false;
-         return;
-     }
- 
-     SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
-     SetProp(mWindow, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
-@@ -305,27 +305,27 @@ void Surface::subclassWindow()
- void Surface::unsubclassWindow()
- {
-     if(!mWindowSubclassed)
-     {
-         return;
-     }
- 
-     // un-subclass
--    LONG parentWndFunc = reinterpret_cast<LONG>(GetProp(mWindow, kParentWndProc));
-+    LONG_PTR parentWndFunc = reinterpret_cast<LONG_PTR>(GetProp(mWindow, kParentWndProc));
- 
-     // Check the windowproc is still SurfaceWindowProc.
-     // If this assert fails, then it is likely the application has subclassed the
-     // hwnd as well and did not unsubclass before destroying its EGL context. The
-     // application should be modified to either subclass before initializing the
-     // EGL context, or to unsubclass before destroying the EGL context.
-     if(parentWndFunc)
-     {
--        LONG prevWndFunc = SetWindowLong(mWindow, GWL_WNDPROC, parentWndFunc);
--        ASSERT(prevWndFunc == reinterpret_cast<LONG>(SurfaceWindowProc));
-+        LONG_PTR prevWndFunc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, parentWndFunc);
-+        ASSERT(prevWndFunc == reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
-     }
- 
-     RemoveProp(mWindow, kSurfaceProperty);
-     RemoveProp(mWindow, kParentWndProc);
-     mWindowSubclassed = false;
- }
- 
- bool Surface::checkForOutOfDateSwapChain()
-diff --git a/gfx/angle/src/libGLESv2/VertexDataManager.cpp b/gfx/angle/src/libGLESv2/VertexDataManager.cpp
---- a/gfx/angle/src/libGLESv2/VertexDataManager.cpp
-+++ b/gfx/angle/src/libGLESv2/VertexDataManager.cpp
-@@ -50,24 +50,24 @@ VertexDataManager::~VertexDataManager()
-     delete mStreamingBuffer;
- 
-     for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
-     {
-         delete mCurrentValueBuffer[i];
-     }
- }
- 
--UINT VertexDataManager::writeAttributeData(ArrayVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute)
-+std::size_t VertexDataManager::writeAttributeData(ArrayVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute)
- {
-     Buffer *buffer = attribute.mBoundBuffer.get();
- 
-     int inputStride = attribute.stride();
-     int elementSize = attribute.typeSize();
-     const FormatConverter &converter = formatConverter(attribute);
--    UINT streamOffset = 0;
-+    std::size_t streamOffset = 0;
- 
-     void *output = NULL;
-     
-     if (vertexBuffer)
-     {
-         output = vertexBuffer->map(attribute, spaceRequired(attribute, count), &streamOffset);
-     }
- 
-@@ -198,17 +198,17 @@ GLenum VertexDataManager::prepareVertexD
-                     return GL_INVALID_OPERATION;
-                 }
- 
-                 const FormatConverter &converter = formatConverter(attribs[i]);
- 
-                 StaticVertexBuffer *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL;
-                 ArrayVertexBuffer *vertexBuffer = staticBuffer ? staticBuffer : static_cast<ArrayVertexBuffer*>(mStreamingBuffer);
- 
--                UINT streamOffset = -1;
-+                std::size_t streamOffset = -1;
- 
-                 if (staticBuffer)
-                 {
-                     streamOffset = staticBuffer->lookupAttribute(attribs[i]);
- 
-                     if (streamOffset == -1)
-                     {
-                         // Convert the entire buffer
-@@ -666,17 +666,17 @@ void StreamingVertexBuffer::reserveRequi
- StaticVertexBuffer::StaticVertexBuffer(IDirect3DDevice9 *device) : ArrayVertexBuffer(device, 0, D3DUSAGE_WRITEONLY)
- {
- }
- 
- StaticVertexBuffer::~StaticVertexBuffer()
- {
- }
- 
--void *StaticVertexBuffer::map(const VertexAttribute &attribute, std::size_t requiredSpace, UINT *streamOffset)
-+void *StaticVertexBuffer::map(const VertexAttribute &attribute, std::size_t requiredSpace, std::size_t *streamOffset)
- {
-     void *mapPtr = NULL;
- 
-     if (mVertexBuffer)
-     {
-         HRESULT result = mVertexBuffer->Lock(mWritePosition, requiredSpace, &mapPtr, 0);
-         
-         if (FAILED(result))
-diff --git a/gfx/angle/src/libGLESv2/VertexDataManager.h b/gfx/angle/src/libGLESv2/VertexDataManager.h
---- a/gfx/angle/src/libGLESv2/VertexDataManager.h
-+++ b/gfx/angle/src/libGLESv2/VertexDataManager.h
-@@ -30,17 +30,17 @@ struct TranslatedAttribute
-     UINT stride;   // 0 means not to advance the read pointer at all
- 
-     IDirect3DVertexBuffer9 *vertexBuffer;
- };
- 
- class VertexBuffer
- {
-   public:
--    VertexBuffer(IDirect3DDevice9 *device, UINT size, DWORD usageFlags);
-+    VertexBuffer(IDirect3DDevice9 *device, std::size_t size, DWORD usageFlags);
-     virtual ~VertexBuffer();
- 
-     void unmap();
- 
-     IDirect3DVertexBuffer9 *getBuffer() const;
- 
-   protected:
-     IDirect3DDevice9 *const mDevice;
-@@ -55,60 +55,60 @@ class ConstantVertexBuffer : public Vert
-   public:
-     ConstantVertexBuffer(IDirect3DDevice9 *device, float x, float y, float z, float w);
-     ~ConstantVertexBuffer();
- };
- 
- class ArrayVertexBuffer : public VertexBuffer
- {
-   public:
--    ArrayVertexBuffer(IDirect3DDevice9 *device, UINT size, DWORD usageFlags);
-+    ArrayVertexBuffer(IDirect3DDevice9 *device, std::size_t size, DWORD usageFlags);
-     ~ArrayVertexBuffer();
- 
--    UINT size() const { return mBufferSize; }
--    virtual void *map(const VertexAttribute &attribute, UINT requiredSpace, UINT *streamOffset) = 0;
-+    std::size_t size() const { return mBufferSize; }
-+    virtual void *map(const VertexAttribute &attribute, std::size_t requiredSpace, std::size_t *streamOffset) = 0;
-     virtual void reserveRequiredSpace() = 0;
-     void addRequiredSpace(UINT requiredSpace);
- 
-   protected:
--    UINT mBufferSize;
--    UINT mWritePosition;
--    UINT mRequiredSpace;
-+    std::size_t mBufferSize;
-+    std::size_t mWritePosition;
-+    std::size_t mRequiredSpace;
- };
- 
- class StreamingVertexBuffer : public ArrayVertexBuffer
- {
-   public:
--    StreamingVertexBuffer(IDirect3DDevice9 *device, UINT initialSize);
-+    StreamingVertexBuffer(IDirect3DDevice9 *device, std::size_t initialSize);
-     ~StreamingVertexBuffer();
- 
--    void *map(const VertexAttribute &attribute, UINT requiredSpace, UINT *streamOffset);
-+    void *map(const VertexAttribute &attribute, std::size_t requiredSpace, std::size_t *streamOffset);
-     void reserveRequiredSpace();
- };
- 
- class StaticVertexBuffer : public ArrayVertexBuffer
- {
-   public:
-     explicit StaticVertexBuffer(IDirect3DDevice9 *device);
-     ~StaticVertexBuffer();
- 
--    void *map(const VertexAttribute &attribute, UINT requiredSpace, UINT *streamOffset);
-+    void *map(const VertexAttribute &attribute, std::size_t requiredSpace, std::size_t *streamOffset);
-     void reserveRequiredSpace();
- 
-     UINT lookupAttribute(const VertexAttribute &attribute);   // Returns the offset into the vertex buffer, or -1 if not found
- 
-   private:
-     struct VertexElement
-     {
-         GLenum type;
-         GLint size;
-         bool normalized;
-         int attributeOffset;
- 
--        UINT streamOffset;
-+        std::size_t streamOffset;
-     };
- 
-     std::vector<VertexElement> mCache;
- };
- 
- class VertexDataManager
- {
-   public:
-@@ -117,18 +117,18 @@ class VertexDataManager
- 
-     void dirtyCurrentValue(int index) { mDirtyCurrentValue[index] = true; }
- 
-     GLenum prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *outAttribs);
- 
-   private:
-     DISALLOW_COPY_AND_ASSIGN(VertexDataManager);
- 
--    UINT spaceRequired(const VertexAttribute &attrib, std::size_t count) const;
--    UINT writeAttributeData(ArrayVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute);
-+    std::size_t spaceRequired(const VertexAttribute &attrib, std::size_t count) const;
-+    std::size_t writeAttributeData(ArrayVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute);
- 
-     Context *const mContext;
-     IDirect3DDevice9 *const mDevice;
- 
-     StreamingVertexBuffer *mStreamingBuffer;
- 
-     bool mDirtyCurrentValue[MAX_VERTEX_ATTRIBS];
-     ConstantVertexBuffer *mCurrentValueBuffer[MAX_VERTEX_ATTRIBS];
new file mode 100644
--- /dev/null
+++ b/gfx/angle/extensions/ANGLE_texture_compression_dxt.txt
@@ -0,0 +1,73 @@
+Name
+
+    ANGLE_texture_compression_dxt
+
+Name Strings
+
+    GL_ANGLE_texture_compression_dxt3
+    GL_ANGLE_texture_compression_dxt5
+
+Contributors
+
+    Gregg Tavares, Google Inc.
+    Daniel Koch, TransGaming Inc.
+    Al Patrick, Google Inc.
+
+Contacts
+
+    Gregg Tavares, Google Inc. (gman 'at' google 'dot' com)
+
+Status
+
+    Implemented in ANGLE ES2
+
+Version
+
+    Last Modified Date: Aug 2, 2011
+
+Number
+
+    OpenGL ES Extension #..
+
+Dependencies
+
+    Requires OpenGL ES 2.0.
+
+    The extension is written against the OpenGL ES 2.0 specification.
+
+Overview
+
+    These extensions are exactly the same as EXT_texture_compression_dxt1
+    except they expose the formats COMPRESSED_RGBA_S3TC_DXT3_ANGLE and
+    COMPRESSED_RGBA_S3TC_DXT5_ANGLE respectively.
+
+    See EXT_texture_compression_dxt1 for the full list of changes. Also
+    see EXT_texture_compression_s3tc for a description of the formats.
+
+New Procedures and Functions
+
+    None.
+
+New Types
+
+    None.
+
+New Tokens
+
+    Accepted by the <internalformat> parameter of CompressedTexImage2D
+    and the <format> parameter of CompressedTexSubImage2D:
+
+    COMPRESSED_RGBA_S3TC_DXT3_ANGLE                   0x83F2
+    COMPRESSED_RGBA_S3TC_DXT5_ANGLE                   0x83F3
+
+Errors
+
+    None.
+
+New State
+
+    None.
+
+Revision History
+
+
new file mode 100644
--- /dev/null
+++ b/gfx/angle/extensions/EGL_ANGLE_software_display.txt
@@ -0,0 +1,63 @@
+Name
+
+    ANGLE_software_display
+
+Name Strings
+
+    EGL_ANGLE_software_display
+
+Contributors
+
+    John Bauman
+    Daniel Koch
+
+Contacts
+
+    John Bauman, Google Inc. (jbauman 'at' chromium.org)
+
+Status
+
+    In progress
+
+Version
+
+    Version 1, July 12, 2011
+
+Number
+
+    EGL Extension #??
+
+Dependencies
+
+    This extension is written against the wording of the EGL 1.4
+    Specification. 
+
+Overview
+
+    This extension allows for receiving a device that uses software rendering.
+
+New Types
+
+    None
+
+New Procedures and Functions
+
+    None
+
+New Tokens
+
+    None
+
+Additions to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors)
+
+    Add before the last sentence of the first paragraph of section 3.2,
+    "Initialization":
+
+    "If <display_id> is EGL_SOFTWARE_DISPLAY_ANGLE, a display that will render
+    everything in software will be returned."
+
+Issues
+
+Revision History
+
+    Version 1, 2011/07/12 - first draft.
deleted file mode 100644
--- a/gfx/angle/fix-angle-surface-assert.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-# HG changeset patch
-# Parent 9869d707ee367a9a108b663c71388cdea4abb705
-
-diff --git a/gfx/angle/src/libEGL/Surface.cpp b/gfx/angle/src/libEGL/Surface.cpp
---- a/gfx/angle/src/libEGL/Surface.cpp
-+++ b/gfx/angle/src/libEGL/Surface.cpp
-@@ -210,33 +210,33 @@ bool Surface::resetSwapChain(int backbuf
-         }
- 
-         result = device->CreateTexture(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, 1, D3DUSAGE_RENDERTARGET,
-                                        presentParameters.BackBufferFormat, D3DPOOL_DEFAULT, &mOffscreenTexture, pShareHandle);
-     }
- 
-     if (FAILED(result))
-     {
--        ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
-+      ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL);
- 
-         ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result);
-         release();
-         return error(EGL_BAD_ALLOC, false);
-     }
- 
-     if (mConfig->mDepthStencilFormat != D3DFMT_UNKNOWN)
-     {
-         result = device->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight,
-                                                    presentParameters.AutoDepthStencilFormat, presentParameters.MultiSampleType,
-                                                    presentParameters.MultiSampleQuality, FALSE, &mDepthStencil, NULL);
-     }
- 
-     if (FAILED(result))
-     {
--        ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
-+        ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL);
- 
-         ERR("Could not create depthstencil surface for new swap chain: %08lX", result);
-         release();
-         return error(EGL_BAD_ALLOC, false);
-     }
- 
-     if (mWindow) {
-         mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mRenderTarget);
--- a/gfx/angle/include/EGL/eglext.h
+++ b/gfx/angle/include/EGL/eglext.h
@@ -1,17 +1,17 @@
 #ifndef __eglext_h_
 #define __eglext_h_
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /*
-** Copyright (c) 2007-2009 The Khronos Group Inc.
+** Copyright (c) 2007-2010 The Khronos Group Inc.
 **
 ** Permission is hereby granted, free of charge, to any person obtaining a
 ** copy of this software and/or associated documentation files (the
 ** "Materials"), to deal in the Materials without restriction, including
 ** without limitation the rights to use, copy, modify, merge, publish,
 ** distribute, sublicense, and/or sell copies of the Materials, and to
 ** permit persons to whom the Materials are furnished to do so, subject to
 ** the following conditions:
@@ -29,18 +29,18 @@ extern "C" {
 */
 
 #include <EGL/eglplatform.h>
 
 /*************************************************************/
 
 /* Header file version number */
 /* Current version at http://www.khronos.org/registry/egl/ */
-/* $Revision: 10795 $ on $Date: 2010-03-19 17:04:17 -0700 (Fri, 19 Mar 2010) $ */
-#define EGL_EGLEXT_VERSION 5
+/* $Revision: 15052 $ on $Date: 2011-07-06 17:43:46 -0700 (Wed, 06 Jul 2011) $ */
+#define EGL_EGLEXT_VERSION 10
 
 #ifndef EGL_KHR_config_attribs
 #define EGL_KHR_config_attribs 1
 #define EGL_CONFORMANT_KHR			0x3042	/* EGLConfig attribute */
 #define EGL_VG_COLORSPACE_LINEAR_BIT_KHR	0x0020	/* EGL_SURFACE_TYPE bitfield */
 #define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR		0x0040	/* EGL_SURFACE_TYPE bitfield */
 #endif
 
@@ -115,16 +115,17 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLD
 #define EGL_GL_TEXTURE_ZOFFSET_KHR		0x30BD	/* eglCreateImageKHR attribute */
 #endif
 
 #ifndef EGL_KHR_gl_renderbuffer_image
 #define EGL_KHR_gl_renderbuffer_image 1
 #define EGL_GL_RENDERBUFFER_KHR			0x30B9	/* eglCreateImageKHR target */
 #endif
 
+#if KHRONOS_SUPPORT_INT64   /* EGLTimeKHR requires 64-bit uint support */
 #ifndef EGL_KHR_reusable_sync
 #define EGL_KHR_reusable_sync 1
 
 typedef void* EGLSyncKHR;
 typedef khronos_utime_nanoseconds_t EGLTimeKHR;
 
 #define EGL_SYNC_STATUS_KHR			0x30F1
 #define EGL_SIGNALED_KHR			0x30F2
@@ -144,16 +145,17 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSignalS
 EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
 #endif /* EGL_EGLEXT_PROTOTYPES */
 typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
 typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync);
 typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
 typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
 typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
 #endif
+#endif
 
 #ifndef EGL_KHR_image_base
 #define EGL_KHR_image_base 1
 /* Most interfaces defined by EGL_KHR_image_pixmap above */
 #define EGL_IMAGE_PRESERVED_KHR			0x30D2	/* eglCreateImageKHR attribute */
 #endif
 
 #ifndef EGL_KHR_image_pixmap
@@ -164,72 +166,175 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLG
 #ifndef EGL_IMG_context_priority
 #define EGL_IMG_context_priority 1
 #define EGL_CONTEXT_PRIORITY_LEVEL_IMG		0x3100
 #define EGL_CONTEXT_PRIORITY_HIGH_IMG		0x3101
 #define EGL_CONTEXT_PRIORITY_MEDIUM_IMG		0x3102
 #define EGL_CONTEXT_PRIORITY_LOW_IMG		0x3103
 #endif
 
+#ifndef EGL_KHR_lock_surface2
+#define EGL_KHR_lock_surface2 1
+#define EGL_BITMAP_PIXEL_SIZE_KHR		0x3110
+#endif
+
 #ifndef EGL_NV_coverage_sample
 #define EGL_NV_coverage_sample 1
 #define EGL_COVERAGE_BUFFERS_NV 0x30E0
 #define EGL_COVERAGE_SAMPLES_NV 0x30E1
 #endif
 
 #ifndef EGL_NV_depth_nonlinear
 #define EGL_NV_depth_nonlinear 1
 #define EGL_DEPTH_ENCODING_NV 0x30E2
 #define EGL_DEPTH_ENCODING_NONE_NV 0
 #define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3
 #endif
 
+#if KHRONOS_SUPPORT_INT64   /* EGLTimeNV requires 64-bit uint support */
 #ifndef EGL_NV_sync
 #define EGL_NV_sync 1
 #define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV	0x30E6
 #define EGL_SYNC_STATUS_NV			0x30E7
 #define EGL_SIGNALED_NV				0x30E8
 #define EGL_UNSIGNALED_NV			0x30E9
 #define EGL_SYNC_FLUSH_COMMANDS_BIT_NV		0x0001
 #define EGL_FOREVER_NV				0xFFFFFFFFFFFFFFFFull
 #define EGL_ALREADY_SIGNALED_NV			0x30EA
 #define EGL_TIMEOUT_EXPIRED_NV			0x30EB
 #define EGL_CONDITION_SATISFIED_NV		0x30EC
 #define EGL_SYNC_TYPE_NV			0x30ED
 #define EGL_SYNC_CONDITION_NV			0x30EE
 #define EGL_SYNC_FENCE_NV			0x30EF
 #define EGL_NO_SYNC_NV				((EGLSyncNV)0)
 typedef void* EGLSyncNV;
-typedef unsigned long long EGLTimeNV;
+typedef khronos_utime_nanoseconds_t EGLTimeNV;
 #ifdef EGL_EGLEXT_PROTOTYPES
 EGLSyncNV eglCreateFenceSyncNV (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
 EGLBoolean eglDestroySyncNV (EGLSyncNV sync);
 EGLBoolean eglFenceNV (EGLSyncNV sync);
 EGLint eglClientWaitSyncNV (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
 EGLBoolean eglSignalSyncNV (EGLSyncNV sync, EGLenum mode);
 EGLBoolean eglGetSyncAttribNV (EGLSyncNV sync, EGLint attribute, EGLint *value);
 #endif /* EGL_EGLEXT_PROTOTYPES */
 typedef EGLSyncNV (EGLAPIENTRYP PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
 typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync);
 typedef EGLBoolean (EGLAPIENTRYP PFNEGLFENCENVPROC) (EGLSyncNV sync);
 typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCNVPROC) (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
 typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCNVPROC) (EGLSyncNV sync, EGLenum mode);
 typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBNVPROC) (EGLSyncNV sync, EGLint attribute, EGLint *value);
 #endif
+#endif
+
+#if KHRONOS_SUPPORT_INT64   /* Dependent on EGL_KHR_reusable_sync which requires 64-bit uint support */
+#ifndef EGL_KHR_fence_sync
+#define EGL_KHR_fence_sync 1
+/* Reuses most tokens and entry points from EGL_KHR_reusable_sync */
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR	0x30F0
+#define EGL_SYNC_CONDITION_KHR			0x30F8
+#define EGL_SYNC_FENCE_KHR			0x30F9
+#endif
+#endif
+
+#ifndef EGL_HI_clientpixmap
+#define EGL_HI_clientpixmap 1
+
+/* Surface Attribute */
+#define EGL_CLIENT_PIXMAP_POINTER_HI		0x8F74
+/*
+ * Structure representing a client pixmap
+ * (pixmap's data is in client-space memory).
+ */
+struct EGLClientPixmapHI
+{
+	void*		pData;
+	EGLint		iWidth;
+	EGLint		iHeight;
+	EGLint		iStride;
+};
+
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI(EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI* pixmap);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEHIPROC) (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI* pixmap);
+#endif	/* EGL_HI_clientpixmap */
+
+#ifndef EGL_HI_colorformats
+#define EGL_HI_colorformats 1
+/* Config Attribute */
+#define EGL_COLOR_FORMAT_HI			0x8F70
+/* Color Formats */
+#define EGL_COLOR_RGB_HI			0x8F71
+#define EGL_COLOR_RGBA_HI			0x8F72
+#define EGL_COLOR_ARGB_HI			0x8F73
+#endif /* EGL_HI_colorformats */
+
+#ifndef EGL_MESA_drm_image
+#define EGL_MESA_drm_image 1
+#define EGL_DRM_BUFFER_FORMAT_MESA		0x31D0	    /* CreateDRMImageMESA attribute */
+#define EGL_DRM_BUFFER_USE_MESA			0x31D1	    /* CreateDRMImageMESA attribute */
+#define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA	0x31D2	    /* EGL_IMAGE_FORMAT_MESA attribute value */
+#define EGL_DRM_BUFFER_MESA			0x31D3	    /* eglCreateImageKHR target */
+#define EGL_DRM_BUFFER_STRIDE_MESA		0x31D4
+#define EGL_DRM_BUFFER_USE_SCANOUT_MESA		0x00000001  /* EGL_DRM_BUFFER_USE_MESA bits */
+#define EGL_DRM_BUFFER_USE_SHARE_MESA		0x00000002  /* EGL_DRM_BUFFER_USE_MESA bits */
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLImageKHR EGLAPIENTRY eglCreateDRMImageMESA (EGLDisplay dpy, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglExportDRMImageMESA (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
+#endif
+
+#ifndef EGL_NV_post_sub_buffer
+#define EGL_NV_post_sub_buffer 1
+#define EGL_POST_SUB_BUFFER_SUPPORTED_NV	0x30BE
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglPostSubBufferNV (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLPOSTSUBBUFFERNVPROC) (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
+#endif
 
 #ifndef EGL_ANGLE_query_surface_pointer
 #define EGL_ANGLE_query_surface_pointer 1
 #ifdef EGL_EGLEXT_PROTOTYPES
 EGLAPI EGLBoolean eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
 #endif
 typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
 #endif
 
 #ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle
-#define EGL_ANGLE_surface_d3d_texture_2d_share_handle
-#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200
+#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1
+#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE	0x3200
+#endif
+
+#ifndef EGL_ANGLE_software_display
+#define EGL_ANGLE_software_display 1
+#define EGL_SOFTWARE_DISPLAY_ANGLE ((EGLNativeDisplayType)-1)
+#endif
+
+#ifndef EGL_NV_coverage_sample_resolve
+#define EGL_NV_coverage_sample_resolve 1
+#define EGL_COVERAGE_SAMPLE_RESOLVE_NV		0x3131
+#define EGL_COVERAGE_SAMPLE_RESOLVE_DEFAULT_NV	0x3132
+#define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV	0x3133
+#endif
+
+#if KHRONOS_SUPPORT_INT64   /* EGLTimeKHR requires 64-bit uint support */
+#ifndef EGL_NV_system_time
+#define EGL_NV_system_time 1
+
+typedef khronos_utime_nanoseconds_t EGLuint64NV;
+
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeFrequencyNV(void);
+EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV(void);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC) (void);
+typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC) (void);
+#endif
 #endif
 
 #ifdef __cplusplus
 }
 #endif
 
 #endif
--- a/gfx/angle/include/EGL/eglplatform.h
+++ b/gfx/angle/include/EGL/eglplatform.h
@@ -20,17 +20,17 @@
 ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 ** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
 */
 
 /* Platform-specific types and definitions for egl.h
- * $Revision: 9724 $ on $Date: 2009-12-02 02:05:33 -0800 (Wed, 02 Dec 2009) $
+ * $Revision: 12306 $ on $Date: 2010-08-25 09:51:28 -0700 (Wed, 25 Aug 2010) $
  *
  * Adopters may modify khrplatform.h and this file to suit their platform.
  * You are encouraged to submit all modifications to the Khronos group so that
  * they can be included in future versions of this file.  Please submit changes
  * by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla)
  * by filing a bug against product "EGL" component "Registry".
  */
 
@@ -55,16 +55,21 @@
 #endif
 #define EGLAPIENTRYP EGLAPIENTRY*
 
 /* The types NativeDisplayType, NativeWindowType, and NativePixmapType
  * are aliases of window-system-dependent types, such as X Display * or
  * Windows Device Context. They must be defined in platform-specific
  * code below. The EGL-prefixed versions of Native*Type are the same
  * types, renamed in EGL 1.3 so all types in the API start with "EGL".
+ *
+ * Khronos STRONGLY RECOMMENDS that you use the default definitions
+ * provided below, since these changes affect both binary and source
+ * portability of applications using EGL running on different EGL
+ * implementations.
  */
 
 #if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
 #ifndef WIN32_LEAN_AND_MEAN
 #define WIN32_LEAN_AND_MEAN 1
 #endif
 #include <windows.h>
 
@@ -73,16 +78,22 @@ typedef HBITMAP EGLNativePixmapType;
 typedef HWND    EGLNativeWindowType;
 
 #elif defined(__WINSCW__) || defined(__SYMBIAN32__)  /* Symbian */
 
 typedef int   EGLNativeDisplayType;
 typedef void *EGLNativeWindowType;
 typedef void *EGLNativePixmapType;
 
+#elif defined(WL_EGL_PLATFORM)
+
+typedef struct wl_display     *EGLNativeDisplayType;
+typedef struct wl_egl_pixmap  *EGLNativePixmapType;
+typedef struct wl_egl_window  *EGLNativeWindowType;
+
 #elif defined(__unix__)
 
 /* X11 (tentative)  */
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 
 typedef Display *EGLNativeDisplayType;
 typedef Pixmap   EGLNativePixmapType;
--- a/gfx/angle/include/GLES2/gl2ext.h
+++ b/gfx/angle/include/GLES2/gl2ext.h
@@ -1,12 +1,12 @@
 #ifndef __gl2ext_h_
 #define __gl2ext_h_
 
-/* $Revision: 10798 $ on $Date:: 2010-03-19 17:34:30 -0700 #$ */
+/* $Revision: 15049 $ on $Date:: 2011-07-06 17:28:16 -0700 #$ */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /*
  * This document is licensed under the SGI Free Software B License Version
  * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ .
@@ -52,16 +52,25 @@ extern "C" {
 /* GL_OES_depth_texture */
 /* No new tokens introduced by this extension. */
 
 /* GL_OES_EGL_image */
 #ifndef GL_OES_EGL_image
 typedef void* GLeglImageOES;
 #endif
 
+/* GL_OES_EGL_image_external */
+#ifndef GL_OES_EGL_image_external
+/* GLeglImageOES defined in GL_OES_EGL_image already. */
+#define GL_TEXTURE_EXTERNAL_OES                                 0x8D65
+#define GL_SAMPLER_EXTERNAL_OES                                 0x8D66
+#define GL_TEXTURE_BINDING_EXTERNAL_OES                         0x8D67
+#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES                     0x8D68
+#endif
+
 /* GL_OES_element_index_uint */
 #ifndef GL_OES_element_index_uint
 #define GL_UNSIGNED_INT                                         0x1405
 #endif
 
 /* GL_OES_get_program_binary */
 #ifndef GL_OES_get_program_binary
 #define GL_PROGRAM_BINARY_LENGTH_OES                            0x8741
@@ -175,16 +184,89 @@ typedef void* GLeglImageOES;
 #endif
 
 /* GL_AMD_program_binary_Z400 */
 #ifndef GL_AMD_program_binary_Z400
 #define GL_Z400_BINARY_AMD                                      0x8740
 #endif
 
 /*------------------------------------------------------------------------*
+ * ANGLE extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_ANGLE_framebuffer_blit */
+#ifndef GL_ANGLE_framebuffer_blit
+#define GL_READ_FRAMEBUFFER_ANGLE                               0x8CA8
+#define GL_DRAW_FRAMEBUFFER_ANGLE                               0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE                       0x8CA6
+#define GL_READ_FRAMEBUFFER_BINDING_ANGLE                       0x8CAA
+#endif
+
+/* GL_ANGLE_framebuffer_multisample */
+#ifndef GL_ANGLE_framebuffer_multisample
+#define GL_RENDERBUFFER_SAMPLES_ANGLE                           0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE             0x8D56
+#define GL_MAX_SAMPLES_ANGLE                                    0x8D57
+#endif
+
+/* GL_ANGLE_texture_compression_dxt3 */
+#ifndef GL_ANGLE_texture_compression_dxt3
+#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE                      0x83F2
+#endif
+
+/* GL_ANGLE_texture_compression_dxt5 */
+#ifndef GL_ANGLE_texture_compression_dxt5
+#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE                      0x83F3
+#endif
+
+/*------------------------------------------------------------------------*
+ * APPLE extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_APPLE_rgb_422 */
+#ifndef GL_APPLE_rgb_422
+#define GL_RGB_422_APPLE                                        0x8A1F
+#define GL_UNSIGNED_SHORT_8_8_APPLE                             0x85BA
+#define GL_UNSIGNED_SHORT_8_8_REV_APPLE                         0x85BB
+#endif
+
+/* GL_APPLE_framebuffer_multisample */
+#ifndef GL_APPLE_framebuffer_multisample
+#define GL_RENDERBUFFER_SAMPLES_APPLE                           0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE             0x8D56
+#define GL_MAX_SAMPLES_APPLE                                    0x8D57
+#define GL_READ_FRAMEBUFFER_APPLE                               0x8CA8
+#define GL_DRAW_FRAMEBUFFER_APPLE                               0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING_APPLE                       0x8CA6
+#define GL_READ_FRAMEBUFFER_BINDING_APPLE                       0x8CAA
+#endif
+
+/* GL_APPLE_texture_format_BGRA8888 */
+#ifndef GL_APPLE_texture_format_BGRA8888
+#define GL_BGRA_EXT                                             0x80E1
+#endif
+
+/* GL_APPLE_texture_max_level */
+#ifndef GL_APPLE_texture_max_level
+#define GL_TEXTURE_MAX_LEVEL_APPLE                              0x813D
+#endif
+
+/*------------------------------------------------------------------------*
+ * ARM extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_ARM_mali_shader_binary */
+#ifndef GL_ARM_mali_shader_binary
+#define GL_MALI_SHADER_BINARY_ARM                               0x8F60
+#endif
+
+/* GL_ARM_rgba8 */
+/* No new tokens introduced by this extension. */
+
+/*------------------------------------------------------------------------*
  * EXT extension tokens
  *------------------------------------------------------------------------*/
 
 /* GL_EXT_blend_minmax */
 #ifndef GL_EXT_blend_minmax
 #define GL_MIN_EXT                                              0x8007
 #define GL_MAX_EXT                                              0x8008
 #endif
@@ -201,16 +283,19 @@ typedef void* GLeglImageOES;
 
 /* GL_EXT_read_format_bgra */
 #ifndef GL_EXT_read_format_bgra
 #define GL_BGRA_EXT                                             0x80E1
 #define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT                       0x8365
 #define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT                       0x8366
 #endif
 
+/* GL_EXT_shader_texture_lod */
+/* No new tokens introduced by this extension. */
+
 /* GL_EXT_texture_filter_anisotropic */
 #ifndef GL_EXT_texture_filter_anisotropic
 #define GL_TEXTURE_MAX_ANISOTROPY_EXT                           0x84FE
 #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT                       0x84FF
 #endif
 
 /* GL_EXT_texture_format_BGRA8888 */
 #ifndef GL_EXT_texture_format_BGRA8888
@@ -223,16 +308,32 @@ typedef void* GLeglImageOES;
 #endif
 
 /* GL_EXT_texture_compression_dxt1 */
 #ifndef GL_EXT_texture_compression_dxt1
 #define GL_COMPRESSED_RGB_S3TC_DXT1_EXT                         0x83F0
 #define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT                        0x83F1
 #endif
 
+/* GL_EXT_unpack_subimage */
+#ifndef GL_EXT_unpack_subimage
+#define GL_UNPACK_ROW_LENGTH                                    0x0CF2
+#define GL_UNPACK_SKIP_ROWS                                     0x0CF3
+#define GL_UNPACK_SKIP_PIXELS                                   0x0CF4
+#endif
+
+/*------------------------------------------------------------------------*
+ * DMP extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_DMP_shader_binary */
+#ifndef GL_DMP_shader_binary
+#define GL_SHADER_BINARY_DMP                                    0x9250
+#endif
+
 /*------------------------------------------------------------------------*
  * IMG extension tokens
  *------------------------------------------------------------------------*/
 
 /* GL_IMG_program_binary */
 #ifndef GL_IMG_program_binary
 #define GL_SGX_PROGRAM_BINARY_IMG                               0x9130
 #endif
@@ -251,27 +352,28 @@ typedef void* GLeglImageOES;
 /* GL_IMG_texture_compression_pvrtc */
 #ifndef GL_IMG_texture_compression_pvrtc
 #define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG                      0x8C00
 #define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG                      0x8C01
 #define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG                     0x8C02
 #define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG                     0x8C03
 #endif
 
+/* GL_IMG_multisampled_render_to_texture */
+#ifndef GL_IMG_multisampled_render_to_texture
+#define GL_RENDERBUFFER_SAMPLES_IMG                             0x9133
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG               0x9134
+#define GL_MAX_SAMPLES_IMG                                      0x9135
+#define GL_TEXTURE_SAMPLES_IMG                                  0x9136
+#endif
+
 /*------------------------------------------------------------------------*
  * NV extension tokens
  *------------------------------------------------------------------------*/
 
-/* GL_NV_fence */
-#ifndef GL_NV_fence
-#define GL_ALL_COMPLETED_NV                                     0x84F2
-#define GL_FENCE_STATUS_NV                                      0x84F3
-#define GL_FENCE_CONDITION_NV                                   0x84F4
-#endif
-
 /* GL_NV_coverage_sample */
 #ifndef GL_NV_coverage_sample
 #define GL_COVERAGE_COMPONENT_NV                                0x8ED0
 #define GL_COVERAGE_COMPONENT4_NV                               0x8ED1
 #define GL_COVERAGE_ATTACHMENT_NV                               0x8ED2
 #define GL_COVERAGE_BUFFERS_NV                                  0x8ED3
 #define GL_COVERAGE_SAMPLES_NV                                  0x8ED4
 #define GL_COVERAGE_ALL_FRAGMENTS_NV                            0x8ED5
@@ -280,20 +382,100 @@ typedef void* GLeglImageOES;
 #define GL_COVERAGE_BUFFER_BIT_NV                               0x8000
 #endif
 
 /* GL_NV_depth_nonlinear */
 #ifndef GL_NV_depth_nonlinear
 #define GL_DEPTH_COMPONENT16_NONLINEAR_NV                       0x8E2C
 #endif
 
+/* GL_NV_draw_buffers */
+#ifndef GL_NV_draw_buffers
+#define GL_MAX_DRAW_BUFFERS_NV                                  0x8824
+#define GL_DRAW_BUFFER0_NV                                      0x8825
+#define GL_DRAW_BUFFER1_NV                                      0x8826
+#define GL_DRAW_BUFFER2_NV                                      0x8827
+#define GL_DRAW_BUFFER3_NV                                      0x8828
+#define GL_DRAW_BUFFER4_NV                                      0x8829
+#define GL_DRAW_BUFFER5_NV                                      0x882A
+#define GL_DRAW_BUFFER6_NV                                      0x882B
+#define GL_DRAW_BUFFER7_NV                                      0x882C
+#define GL_DRAW_BUFFER8_NV                                      0x882D
+#define GL_DRAW_BUFFER9_NV                                      0x882E
+#define GL_DRAW_BUFFER10_NV                                     0x882F
+#define GL_DRAW_BUFFER11_NV                                     0x8830
+#define GL_DRAW_BUFFER12_NV                                     0x8831
+#define GL_DRAW_BUFFER13_NV                                     0x8832
+#define GL_DRAW_BUFFER14_NV                                     0x8833
+#define GL_DRAW_BUFFER15_NV                                     0x8834
+#define GL_COLOR_ATTACHMENT0_NV                                 0x8CE0
+#define GL_COLOR_ATTACHMENT1_NV                                 0x8CE1
+#define GL_COLOR_ATTACHMENT2_NV                                 0x8CE2
+#define GL_COLOR_ATTACHMENT3_NV                                 0x8CE3
+#define GL_COLOR_ATTACHMENT4_NV                                 0x8CE4
+#define GL_COLOR_ATTACHMENT5_NV                                 0x8CE5
+#define GL_COLOR_ATTACHMENT6_NV                                 0x8CE6
+#define GL_COLOR_ATTACHMENT7_NV                                 0x8CE7
+#define GL_COLOR_ATTACHMENT8_NV                                 0x8CE8
+#define GL_COLOR_ATTACHMENT9_NV                                 0x8CE9
+#define GL_COLOR_ATTACHMENT10_NV                                0x8CEA
+#define GL_COLOR_ATTACHMENT11_NV                                0x8CEB
+#define GL_COLOR_ATTACHMENT12_NV                                0x8CEC
+#define GL_COLOR_ATTACHMENT13_NV                                0x8CED
+#define GL_COLOR_ATTACHMENT14_NV                                0x8CEE
+#define GL_COLOR_ATTACHMENT15_NV                                0x8CEF
+#endif
+
+/* GL_NV_fbo_color_attachments */
+#ifndef GL_NV_fbo_color_attachments
+#define GL_MAX_COLOR_ATTACHMENTS_NV                             0x8CDF
+/* GL_COLOR_ATTACHMENT{0-15}_NV defined in GL_NV_draw_buffers already. */
+#endif
+
+/* GL_NV_fence */
+#ifndef GL_NV_fence
+#define GL_ALL_COMPLETED_NV                                     0x84F2
+#define GL_FENCE_STATUS_NV                                      0x84F3
+#define GL_FENCE_CONDITION_NV                                   0x84F4
+#endif
+
+/* GL_NV_read_buffer */
+#ifndef GL_NV_read_buffer
+#define GL_READ_BUFFER_NV                                       0x0C02
+#endif
+
+/* GL_NV_read_buffer_front */
+/* No new tokens introduced by this extension. */
+
+/* GL_NV_read_depth */
+/* No new tokens introduced by this extension. */
+
+/* GL_NV_read_depth_stencil */
+/* No new tokens introduced by this extension. */
+
+/* GL_NV_read_stencil */
+/* No new tokens introduced by this extension. */
+
+/* GL_NV_texture_compression_s3tc_update */
+/* No new tokens introduced by this extension. */
+
+/* GL_NV_texture_npot_2D_mipmap */
+/* No new tokens introduced by this extension. */
+
 /*------------------------------------------------------------------------*
  * QCOM extension tokens
  *------------------------------------------------------------------------*/
 
+/* GL_QCOM_alpha_test */
+#ifndef GL_QCOM_alpha_test
+#define GL_ALPHA_TEST_QCOM                                      0x0BC0
+#define GL_ALPHA_TEST_FUNC_QCOM                                 0x0BC1
+#define GL_ALPHA_TEST_REF_QCOM                                  0x0BC2
+#endif
+
 /* GL_QCOM_driver_control */
 /* No new tokens introduced by this extension. */
 
 /* GL_QCOM_extended_get */
 #ifndef GL_QCOM_extended_get
 #define GL_TEXTURE_WIDTH_QCOM                                   0x8BD2
 #define GL_TEXTURE_HEIGHT_QCOM                                  0x8BD3
 #define GL_TEXTURE_DEPTH_QCOM                                   0x8BD4
@@ -352,32 +534,22 @@ typedef void* GLeglImageOES;
 #define GL_MULTISAMPLE_BUFFER_BIT3_QCOM                         0x08000000
 #define GL_MULTISAMPLE_BUFFER_BIT4_QCOM                         0x10000000
 #define GL_MULTISAMPLE_BUFFER_BIT5_QCOM                         0x20000000
 #define GL_MULTISAMPLE_BUFFER_BIT6_QCOM                         0x40000000
 #define GL_MULTISAMPLE_BUFFER_BIT7_QCOM                         0x80000000
 #endif
 
 /*------------------------------------------------------------------------*
- * ANGLE extension tokens
+ * VIV extension tokens
  *------------------------------------------------------------------------*/
 
-/* GL_ANGLE_framebuffer_blit */
-#ifndef GL_ANGLE_framebuffer_blit
-#define GL_READ_FRAMEBUFFER_ANGLE         0x8CA8
-#define GL_DRAW_FRAMEBUFFER_ANGLE         0x8CA9
-#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6 // alias GL_FRAMEBUFFER_BINDING
-#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA
-#endif
-
-/* GL_ANGLE_framebuffer_multisample */
-#ifndef GL_ANGLE_framebuffer_multisample
-#define GL_RENDERBUFFER_SAMPLES_ANGLE                   0x8CAB
-#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE     0x8D56
-#define GL_MAX_SAMPLES_ANGLE                            0x8D57
+/* GL_VIV_shader_binary */
+#ifndef GL_VIV_shader_binary
+#define GL_SHADER_BINARY_VIV                                    0x8FC4
 #endif
 
 /*------------------------------------------------------------------------*
  * End of extension tokens, start of corresponding extension functions
  *------------------------------------------------------------------------*/
 
 /*------------------------------------------------------------------------*
  * OES extension functions
@@ -414,16 +586,22 @@ typedef void* GLeglImageOES;
 #ifdef GL_GLEXT_PROTOTYPES
 GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image);
 GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image);
 #endif
 typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image);
 typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image);
 #endif
 
+/* GL_OES_EGL_image_external */
+#ifndef GL_OES_EGL_image_external
+#define GL_OES_EGL_image_external 1
+/* glEGLImageTargetTexture2DOES defined in GL_OES_EGL_image already. */
+#endif
+
 /* GL_OES_element_index_uint */
 #ifndef GL_OES_element_index_uint
 #define GL_OES_element_index_uint 1
 #endif
 
 /* GL_OES_fbo_render_mipmap */
 #ifndef GL_OES_fbo_render_mipmap
 #define GL_OES_fbo_render_mipmap 1
@@ -596,16 +774,92 @@ typedef void (GL_APIENTRYP PFNGLGETPERFM
 #endif
 
 /* GL_AMD_program_binary_Z400 */
 #ifndef GL_AMD_program_binary_Z400
 #define GL_AMD_program_binary_Z400 1
 #endif
 
 /*------------------------------------------------------------------------*
+ * ANGLE extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_ANGLE_framebuffer_blit */
+#ifndef GL_ANGLE_framebuffer_blit
+#define GL_ANGLE_framebuffer_blit 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBlitFramebufferANGLE (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif
+typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif
+
+/* GL_ANGLE_framebuffer_multisample */
+#ifndef GL_ANGLE_framebuffer_multisample
+#define GL_ANGLE_framebuffer_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleANGLE (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+
+/* GL_ANGLE_texture_compression_dxt3 */
+#ifndef GL_ANGLE_texture_compression_dxt3
+#define GL_ANGLE_texture_compression_dxt3 1
+#endif
+
+/* GL_ANGLE_texture_compression_dxt5 */
+#ifndef GL_ANGLE_texture_compression_dxt5
+#define GL_ANGLE_texture_compression_dxt5 1
+#endif
+
+/*------------------------------------------------------------------------*
+ * APPLE extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_APPLE_rgb_422 */
+#ifndef GL_APPLE_rgb_422
+#define GL_APPLE_rgb_422 1
+#endif
+
+/* GL_APPLE_framebuffer_multisample */
+#ifndef GL_APPLE_framebuffer_multisample
+#define GL_APPLE_framebuffer_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleAPPLE (GLenum, GLsizei, GLenum, GLsizei, GLsizei);
+GL_APICALL void GL_APIENTRY glResolveMultisampleFramebufferAPPLE (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC) (void);
+#endif
+
+/* GL_APPLE_texture_format_BGRA8888 */
+#ifndef GL_APPLE_texture_format_BGRA8888
+#define GL_APPLE_texture_format_BGRA8888 1
+#endif
+
+/* GL_APPLE_texture_max_level */
+#ifndef GL_APPLE_texture_max_level
+#define GL_APPLE_texture_max_level 1
+#endif
+
+/*------------------------------------------------------------------------*
+ * ARM extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_ARM_mali_shader_binary */
+#ifndef GL_ARM_mali_shader_binary
+#define GL_ARM_mali_shader_binary 1
+#endif
+
+/* GL_ARM_rgba8 */
+#ifndef GL_ARM_rgba8
+#define GL_ARM_rgba8 1
+#endif
+
+/*------------------------------------------------------------------------*
  * EXT extension functions
  *------------------------------------------------------------------------*/
 
 /* GL_EXT_blend_minmax */
 #ifndef GL_EXT_blend_minmax
 #define GL_EXT_blend_minmax 1
 #endif
 
@@ -628,16 +882,21 @@ typedef void (GL_APIENTRYP PFNGLMULTIDRA
 typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
 #endif
 
 /* GL_EXT_read_format_bgra */
 #ifndef GL_EXT_read_format_bgra
 #define GL_EXT_read_format_bgra 1
 #endif
 
+/* GL_EXT_shader_texture_lod */
+#ifndef GL_EXT_shader_texture_lod
+#define GL_EXT_shader_texture_lod 1
+#endif
+
 /* GL_EXT_texture_filter_anisotropic */
 #ifndef GL_EXT_texture_filter_anisotropic
 #define GL_EXT_texture_filter_anisotropic 1
 #endif
 
 /* GL_EXT_texture_format_BGRA8888 */
 #ifndef GL_EXT_texture_format_BGRA8888
 #define GL_EXT_texture_format_BGRA8888 1
@@ -648,16 +907,30 @@ typedef void (GL_APIENTRYP PFNGLMULTIDRA
 #define GL_EXT_texture_type_2_10_10_10_REV 1
 #endif
 
 /* GL_EXT_texture_compression_dxt1 */
 #ifndef GL_EXT_texture_compression_dxt1
 #define GL_EXT_texture_compression_dxt1 1
 #endif
 
+/* GL_EXT_unpack_subimage */
+#ifndef GL_EXT_unpack_subimage
+#define GL_EXT_unpack_subimage 1
+#endif
+
+/*------------------------------------------------------------------------*
+ * DMP extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_DMP_shader_binary */
+#ifndef GL_DMP_shader_binary
+#define GL_DMP_shader_binary 1
+#endif
+
 /*------------------------------------------------------------------------*
  * IMG extension functions
  *------------------------------------------------------------------------*/
 
 /* GL_IMG_program_binary */
 #ifndef GL_IMG_program_binary
 #define GL_IMG_program_binary 1
 #endif
@@ -672,20 +945,61 @@ typedef void (GL_APIENTRYP PFNGLMULTIDRA
 #define GL_IMG_shader_binary 1
 #endif
 
 /* GL_IMG_texture_compression_pvrtc */
 #ifndef GL_IMG_texture_compression_pvrtc
 #define GL_IMG_texture_compression_pvrtc 1
 #endif
 
+/* GL_IMG_multisampled_render_to_texture */
+#ifndef GL_IMG_multisampled_render_to_texture
+#define GL_IMG_multisampled_render_to_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleIMG (GLenum, GLsizei, GLenum, GLsizei, GLsizei);
+GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleIMG (GLenum, GLenum, GLenum, GLuint, GLint, GLsizei);
+#endif
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMG) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMG) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+#endif
+
 /*------------------------------------------------------------------------*
  * NV extension functions
  *------------------------------------------------------------------------*/
 
+/* GL_NV_coverage_sample */
+#ifndef GL_NV_coverage_sample
+#define GL_NV_coverage_sample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glCoverageMaskNV (GLboolean mask);
+GL_APICALL void GL_APIENTRY glCoverageOperationNV (GLenum operation);
+#endif
+typedef void (GL_APIENTRYP PFNGLCOVERAGEMASKNVPROC) (GLboolean mask);
+typedef void (GL_APIENTRYP PFNGLCOVERAGEOPERATIONNVPROC) (GLenum operation);
+#endif
+
+/* GL_NV_depth_nonlinear */
+#ifndef GL_NV_depth_nonlinear
+#define GL_NV_depth_nonlinear 1
+#endif
+
+/* GL_NV_draw_buffers */
+#ifndef GL_NV_draw_buffers
+#define GL_NV_draw_buffers 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawBuffersNV (GLsizei n, const GLenum *bufs);
+#endif
+typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSNVPROC) (GLsizei n, const GLenum *bufs);
+#endif
+
+/* GL_NV_fbo_color_attachments */
+#ifndef GL_NV_fbo_color_attachments
+#define GL_NV_fbo_color_attachments 1
+#endif
+
 /* GL_NV_fence */
 #ifndef GL_NV_fence
 #define GL_NV_fence 1
 #ifdef GL_GLEXT_PROTOTYPES
 GL_APICALL void GL_APIENTRY glDeleteFencesNV (GLsizei, const GLuint *);
 GL_APICALL void GL_APIENTRY glGenFencesNV (GLsizei, GLuint *);
 GL_APICALL GLboolean GL_APIENTRY glIsFenceNV (GLuint);
 GL_APICALL GLboolean GL_APIENTRY glTestFenceNV (GLuint);
@@ -697,36 +1011,68 @@ typedef void (GL_APIENTRYP PFNGLDELETEFE
 typedef void (GL_APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences);
 typedef GLboolean (GL_APIENTRYP PFNGLISFENCENVPROC) (GLuint fence);
 typedef GLboolean (GL_APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence);
 typedef void (GL_APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params);
 typedef void (GL_APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence);
 typedef void (GL_APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition);
 #endif
 
-/* GL_NV_coverage_sample */
-#ifndef GL_NV_coverage_sample
-#define GL_NV_coverage_sample 1
+/* GL_NV_read_buffer */
+#ifndef GL_NV_read_buffer
+#define GL_NV_read_buffer 1
 #ifdef GL_GLEXT_PROTOTYPES
-GL_APICALL void GL_APIENTRY glCoverageMaskNV (GLboolean mask);
-GL_APICALL void GL_APIENTRY glCoverageOperationNV (GLenum operation);
+GL_APICALL void GL_APIENTRY glReadBufferNV (GLenum mode);
+#endif
+typedef void (GL_APIENTRYP PFNGLREADBUFFERNVPROC) (GLenum mode);
 #endif
-typedef void (GL_APIENTRYP PFNGLCOVERAGEMASKNVPROC) (GLboolean mask);
-typedef void (GL_APIENTRYP PFNGLCOVERAGEOPERATIONNVPROC) (GLenum operation);
+
+/* GL_NV_read_buffer_front */
+#ifndef GL_NV_read_buffer_front
+#define GL_NV_read_buffer_front 1
+#endif
+
+/* GL_NV_read_depth */
+#ifndef GL_NV_read_depth
+#define GL_NV_read_depth 1
 #endif
 
-/* GL_NV_depth_nonlinear */
-#ifndef GL_NV_depth_nonlinear
-#define GL_NV_depth_nonlinear 1
+/* GL_NV_read_depth_stencil */
+#ifndef GL_NV_read_depth_stencil
+#define GL_NV_read_depth_stencil 1
+#endif
+
+/* GL_NV_read_stencil */
+#ifndef GL_NV_read_stencil
+#define GL_NV_read_stencil 1
+#endif
+
+/* GL_NV_texture_compression_s3tc_update */
+#ifndef GL_NV_texture_compression_s3tc_update
+#define GL_NV_texture_compression_s3tc_update 1
+#endif
+
+/* GL_NV_texture_npot_2D_mipmap */
+#ifndef GL_NV_texture_npot_2D_mipmap
+#define GL_NV_texture_npot_2D_mipmap 1
 #endif
 
 /*------------------------------------------------------------------------*
  * QCOM extension functions
  *------------------------------------------------------------------------*/
 
+/* GL_QCOM_alpha_test */
+#ifndef GL_QCOM_alpha_test
+#define GL_QCOM_alpha_test 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glAlphaFuncQCOM (GLenum func, GLclampf ref);
+#endif
+typedef void (GL_APIENTRYP PFNGLALPHAFUNCQCOMPROC) (GLenum func, GLclampf ref);
+#endif
+
 /* GL_QCOM_driver_control */
 #ifndef GL_QCOM_driver_control
 #define GL_QCOM_driver_control 1
 #ifdef GL_GLEXT_PROTOTYPES
 GL_APICALL void GL_APIENTRY glGetDriverControlsQCOM (GLint *num, GLsizei size, GLuint *driverControls);
 GL_APICALL void GL_APIENTRY glGetDriverControlStringQCOM (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString);
 GL_APICALL void GL_APIENTRY glEnableDriverControlQCOM (GLuint driverControl);
 GL_APICALL void GL_APIENTRY glDisableDriverControlQCOM (GLuint driverControl);
@@ -792,40 +1138,21 @@ typedef void (GL_APIENTRYP PFNGLEXTGETPR
 GL_APICALL void GL_APIENTRY glStartTilingQCOM (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask);
 GL_APICALL void GL_APIENTRY glEndTilingQCOM (GLbitfield preserveMask);
 #endif
 typedef void (GL_APIENTRYP PFNGLSTARTTILINGQCOMPROC) (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask);
 typedef void (GL_APIENTRYP PFNGLENDTILINGQCOMPROC) (GLbitfield preserveMask);
 #endif
 
 /*------------------------------------------------------------------------*
- * ANGLE extension functions
+ * VIV extension tokens
  *------------------------------------------------------------------------*/
 
-/* GL_ANGLE_framebuffer_blit */
-#ifndef GL_ANGLE_framebuffer_blit
-#define GL_ANGLE_framebuffer_blit 1
-#ifdef GL_GLEXT_PROTOTYPES
-GL_APICALL void GL_APIENTRY glBlitFramebufferANGLE (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
-                                                    GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
-                                                    GLbitfield mask, GLenum filter);
-#endif
-typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
-                                                           GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
-                                                           GLbitfield mask, GLenum filter);
-#endif
-
-/* GL_ANGLE_framebuffer_multisample */
-#ifndef GL_ANGLE_framebuffer_multisample
-#define GL_ANGLE_framebuffer_multisample 1
-#ifdef GL_GLEXT_PROTOTYPES
-GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleANGLE (GLenum target, GLsizei samples, GLenum internalformat, 
-                                                                   GLsizei width, GLsizei height);
-#endif
-typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat,
-                                                                          GLsizei width, GLsizei height);
+/* GL_VIV_shader_binary */
+#ifndef GL_VIV_shader_binary
+#define GL_VIV_shader_binary 1
 #endif
 
 #ifdef __cplusplus
 }
 #endif
 
 #endif /* __gl2ext_h_ */
--- a/gfx/angle/include/GLSLANG/ShaderLang.h
+++ b/gfx/angle/include/GLSLANG/ShaderLang.h
@@ -12,17 +12,17 @@
 //
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 // Version number for shader translation API.
 // It is incremented everytime the API changes.
-#define SH_VERSION 104
+#define SH_VERSION 105
 
 //
 // The names of the following enums have been derived by replacing GL prefix
 // with SH. For example, SH_INFO_LOG_LENGTH is equivalent to GL_INFO_LOG_LENGTH.
 // The enum values are also equal to the values of their GL counterpart. This
 // is done to make it easier for applications to use the shader library.
 //
 typedef enum {
@@ -31,16 +31,22 @@ typedef enum {
 } ShShaderType;
 
 typedef enum {
   SH_GLES2_SPEC = 0x8B40,
   SH_WEBGL_SPEC = 0x8B41
 } ShShaderSpec;
 
 typedef enum {
+  SH_ESSL_OUTPUT = 0x8B45,
+  SH_GLSL_OUTPUT = 0x8B46,
+  SH_HLSL_OUTPUT = 0x8B47
+} ShShaderOutput;
+
+typedef enum {
   SH_NONE           = 0,
   SH_INT            = 0x1404,
   SH_FLOAT          = 0x1406,
   SH_FLOAT_VEC2     = 0x8B50,
   SH_FLOAT_VEC3     = 0x8B51,
   SH_FLOAT_VEC4     = 0x8B52,
   SH_INT_VEC2       = 0x8B53,
   SH_INT_VEC3       = 0x8B54,
@@ -70,17 +76,21 @@ typedef enum {
 typedef enum {
   SH_VALIDATE                = 0,
   SH_VALIDATE_LOOP_INDEXING  = 0x0001,
   SH_INTERMEDIATE_TREE       = 0x0002,
   SH_OBJECT_CODE             = 0x0004,
   SH_ATTRIBUTES_UNIFORMS     = 0x0008,
   SH_LINE_DIRECTIVES         = 0x0010,
   SH_SOURCE_PATH             = 0x0020,
-  SH_MAP_LONG_VARIABLE_NAMES = 0x0040
+  SH_MAP_LONG_VARIABLE_NAMES = 0x0040,
+  SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX = 0x0080,
+
+  // This is needed only as a workaround for certain OpenGL driver bugs.
+  SH_EMULATE_BUILT_IN_FUNCTIONS = 0x0100
 } ShCompileOptions;
 
 //
 // Driver must call this first, once, before doing any other
 // compiler operations.
 // If the function succeeds, the return value is nonzero, else zero.
 //
 int ShInitialize();
@@ -104,16 +114,17 @@ typedef struct
     int MaxCombinedTextureImageUnits;
     int MaxTextureImageUnits;
     int MaxFragmentUniformVectors;
     int MaxDrawBuffers;
 
     // Extensions.
     // Set to 1 to enable the extension, else 0.
     int OES_standard_derivatives;
+    int OES_EGL_image_external;
 } ShBuiltInResources;
 
 //
 // Initialize built-in resources with minimum expected values.
 //
 void ShInitBuiltInResources(ShBuiltInResources* resources);
 
 //
@@ -123,23 +134,27 @@ void ShInitBuiltInResources(ShBuiltInRes
 //
 // If handle creation fails, 0 will be returned.
 //
 typedef void* ShHandle;
 
 //
 // Driver calls these to create and destroy compiler objects.
 //
-// Returns the handle of constructed compiler.
+// Returns the handle of constructed compiler, null if the requested compiler is
+// not supported.
 // Parameters:
 // type: Specifies the type of shader - SH_FRAGMENT_SHADER or SH_VERTEX_SHADER.
 // spec: Specifies the language spec the compiler must conform to -
 //       SH_GLES2_SPEC or SH_WEBGL_SPEC.
+// output: Specifies the output code type - SH_ESSL_OUTPUT, SH_GLSL_OUTPUT,
+//         or SH_HLSL_OUTPUT.
 // resources: Specifies the built-in resources.
 ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec,
+                             ShShaderOutput output,
                              const ShBuiltInResources* resources);
 void ShDestruct(ShHandle handle);
 
 //
 // Compiles the given shader source.
 // If the function succeeds, the return value is nonzero, else zero.
 // Parameters:
 // handle: Specifies the handle of compiler to be used.
--- a/gfx/angle/samples/translator/translator.cpp
+++ b/gfx/angle/samples/translator/translator.cpp
@@ -48,57 +48,76 @@ void GenerateResources(ShBuiltInResource
     resources->MaxVaryingVectors = 8;
     resources->MaxVertexTextureImageUnits = 0;
     resources->MaxCombinedTextureImageUnits = 8;
     resources->MaxTextureImageUnits = 8;
     resources->MaxFragmentUniformVectors = 16;
     resources->MaxDrawBuffers = 1;
 
     resources->OES_standard_derivatives = 0;
+    resources->OES_EGL_image_external = 0;
 }
 
 int main(int argc, char* argv[])
 {
     TFailCode failCode = ESuccess;
 
     int compileOptions = 0;
     int numCompiles = 0;
     ShHandle vertexCompiler = 0;
     ShHandle fragmentCompiler = 0;
     char* buffer = 0;
     int bufferLen = 0;
     int numAttribs = 0, numUniforms = 0;
+    ShShaderOutput output = SH_ESSL_OUTPUT;
 
     ShInitialize();
 
     ShBuiltInResources resources;
     GenerateResources(&resources);
 
     argc--;
     argv++;
     for (; (argc >= 1) && (failCode == ESuccess); argc--, argv++) {
         if (argv[0][0] == '-') {
             switch (argv[0][1]) {
             case 'i': compileOptions |= SH_INTERMEDIATE_TREE; break;
             case 'm': compileOptions |= SH_MAP_LONG_VARIABLE_NAMES; break;
             case 'o': compileOptions |= SH_OBJECT_CODE; break;
             case 'u': compileOptions |= SH_ATTRIBUTES_UNIFORMS; break;
+            case 'l': compileOptions |= SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX; break;
+            case 'e': compileOptions |= SH_EMULATE_BUILT_IN_FUNCTIONS; break;
+            case 'b':
+                if (argv[0][2] == '=') {
+                    switch (argv[0][3]) {
+                    case 'e': output = SH_ESSL_OUTPUT; break;
+                    case 'g': output = SH_GLSL_OUTPUT; break;
+                    case 'h': output = SH_HLSL_OUTPUT; break;
+                    default: failCode = EFailUsage;
+                    }
+                } else {
+                    failCode = EFailUsage;
+                }
+                break;
+            case 'a': resources.OES_EGL_image_external = 1; break;
             default: failCode = EFailUsage;
             }
         } else {
             ShHandle compiler = 0;
             switch (FindShaderType(argv[0])) {
             case SH_VERTEX_SHADER:
                 if (vertexCompiler == 0)
-                    vertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_GLES2_SPEC, &resources);
+                    vertexCompiler = ShConstructCompiler(
+                        SH_VERTEX_SHADER, SH_GLES2_SPEC, output, &resources);
                 compiler = vertexCompiler;
                 break;
             case SH_FRAGMENT_SHADER:
                 if (fragmentCompiler == 0)
-                    fragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_GLES2_SPEC, &resources);
+                    fragmentCompiler = ShConstructCompiler(
+                        SH_FRAGMENT_SHADER, SH_GLES2_SPEC, output, &resources);
                 compiler = fragmentCompiler;
                 break;
             default: break;
             }
             if (compiler) {
               bool compiled = CompileFile(argv[0], compiler, compileOptions);
 
               LogMsg("BEGIN", "COMPILER", numCompiles, "INFO LOG");
@@ -154,22 +173,28 @@ int main(int argc, char* argv[])
     return failCode;
 }
 
 //
 //   print usage to stdout
 //
 void usage()
 {
-    printf("Usage: translate [-i -m -o -u] file1 file2 ...\n"
-        "Where: filename = filename ending in .frag or .vert\n"
-        "       -i = print intermediate tree\n"
-        "       -m = map long variable names\n"
-        "       -o = print translated code\n"
-        "       -u = print active attribs and uniforms\n");
+    printf("Usage: translate [-i -m -o -u -l -e -b=e -b=g -b=h -a] file1 file2 ...\n"
+        "Where: filename : filename ending in .frag or .vert\n"
+        "       -i       : print intermediate tree\n"
+        "       -m       : map long variable names\n"
+        "       -o       : print translated code\n"
+        "       -u       : print active attribs and uniforms\n"
+        "       -l       : unroll for-loops with integer indices\n"
+        "       -e       : emulate certain built-in functions (workaround for driver bugs)\n"
+        "       -b=e     : output GLSL ES code (this is by default)\n"
+        "       -b=g     : output GLSL code\n"
+        "       -b=h     : output HLSL code\n"
+        "       -a       : enable GL_OES_EGL_image_external\n");
 }
 
 //
 //   Deduce the shader type from the filename.  Files must end in one of the
 //   following extensions:
 //
 //   .frag*    = fragment shader
 //   .vert*    = vertex shader
--- a/gfx/angle/src/ANGLE.sln
+++ b/gfx/angle/src/ANGLE.sln
@@ -16,33 +16,51 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C9
 		{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD} = {5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "translator_common", "compiler\translator_common.vcproj", "{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
 		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
 		{E746FCA9-64C3-433E-85E8-9A5A67AB7ED6}.Debug|Win32.ActiveCfg = Debug|Win32
 		{E746FCA9-64C3-433E-85E8-9A5A67AB7ED6}.Debug|Win32.Build.0 = Debug|Win32
+		{E746FCA9-64C3-433E-85E8-9A5A67AB7ED6}.Debug|x64.ActiveCfg = Debug|x64
+		{E746FCA9-64C3-433E-85E8-9A5A67AB7ED6}.Debug|x64.Build.0 = Debug|x64
 		{E746FCA9-64C3-433E-85E8-9A5A67AB7ED6}.Release|Win32.ActiveCfg = Release|Win32
 		{E746FCA9-64C3-433E-85E8-9A5A67AB7ED6}.Release|Win32.Build.0 = Release|Win32
+		{E746FCA9-64C3-433E-85E8-9A5A67AB7ED6}.Release|x64.ActiveCfg = Release|x64
+		{E746FCA9-64C3-433E-85E8-9A5A67AB7ED6}.Release|x64.Build.0 = Release|x64
 		{B5871A7A-968C-42E3-A33B-981E6F448E78}.Debug|Win32.ActiveCfg = Debug|Win32
 		{B5871A7A-968C-42E3-A33B-981E6F448E78}.Debug|Win32.Build.0 = Debug|Win32
+		{B5871A7A-968C-42E3-A33B-981E6F448E78}.Debug|x64.ActiveCfg = Debug|x64
+		{B5871A7A-968C-42E3-A33B-981E6F448E78}.Debug|x64.Build.0 = Debug|x64
 		{B5871A7A-968C-42E3-A33B-981E6F448E78}.Release|Win32.ActiveCfg = Release|Win32
 		{B5871A7A-968C-42E3-A33B-981E6F448E78}.Release|Win32.Build.0 = Release|Win32
+		{B5871A7A-968C-42E3-A33B-981E6F448E78}.Release|x64.ActiveCfg = Release|x64
+		{B5871A7A-968C-42E3-A33B-981E6F448E78}.Release|x64.Build.0 = Release|x64
 		{5620F0E4-6C43-49BC-A178-B804E1A0C3A7}.Debug|Win32.ActiveCfg = Debug|Win32
 		{5620F0E4-6C43-49BC-A178-B804E1A0C3A7}.Debug|Win32.Build.0 = Debug|Win32
+		{5620F0E4-6C43-49BC-A178-B804E1A0C3A7}.Debug|x64.ActiveCfg = Debug|x64
+		{5620F0E4-6C43-49BC-A178-B804E1A0C3A7}.Debug|x64.Build.0 = Debug|x64
 		{5620F0E4-6C43-49BC-A178-B804E1A0C3A7}.Release|Win32.ActiveCfg = Release|Win32
 		{5620F0E4-6C43-49BC-A178-B804E1A0C3A7}.Release|Win32.Build.0 = Release|Win32
+		{5620F0E4-6C43-49BC-A178-B804E1A0C3A7}.Release|x64.ActiveCfg = Release|x64
+		{5620F0E4-6C43-49BC-A178-B804E1A0C3A7}.Release|x64.Build.0 = Release|x64
 		{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}.Debug|Win32.ActiveCfg = Debug|Win32
 		{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}.Debug|Win32.Build.0 = Debug|Win32
+		{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}.Debug|x64.ActiveCfg = Debug|x64
+		{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}.Debug|x64.Build.0 = Debug|x64
 		{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}.Release|Win32.ActiveCfg = Release|Win32
 		{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}.Release|Win32.Build.0 = Release|Win32
+		{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}.Release|x64.ActiveCfg = Release|x64
+		{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}.Release|x64.Build.0 = Release|x64
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
 	EndGlobalSection
 EndGlobal
 obal
--- a/gfx/angle/src/build_angle.gyp
+++ b/gfx/angle/src/build_angle.gyp
@@ -14,21 +14,27 @@
       'target_name': 'translator_common',
       'type': 'static_library',
       'include_dirs': [
         '.',
         '../include',
       ],
       'sources': [
         'compiler/BaseTypes.h',
+        'compiler/BuiltInFunctionEmulator.cpp',
+        'compiler/BuiltInFunctionEmulator.h',
         'compiler/Common.h',
         'compiler/Compiler.cpp',
         'compiler/ConstantUnion.h',
-        'compiler/compilerdebug.cpp',
-        'compiler/compilerdebug.h',
+        'compiler/debug.cpp',
+        'compiler/debug.h',
+        'compiler/DetectRecursion.cpp',
+        'compiler/DetectRecursion.h',
+        'compiler/ForLoopUnroll.cpp',
+        'compiler/ForLoopUnroll.h',
         'compiler/glslang.h',
         'compiler/glslang_lex.cpp',
         'compiler/glslang_tab.cpp',
         'compiler/glslang_tab.h',
         'compiler/InfoSink.cpp',
         'compiler/InfoSink.h',
         'compiler/Initialize.cpp',
         'compiler/Initialize.h',
@@ -54,17 +60,16 @@
         'compiler/QualifierAlive.h',
         'compiler/RemoveTree.cpp',
         'compiler/RemoveTree.h',
         'compiler/ShaderLang.cpp',
         'compiler/ShHandle.h',
         'compiler/SymbolTable.cpp',
         'compiler/SymbolTable.h',
         'compiler/Types.h',
-        'compiler/unistd.h',
         'compiler/util.cpp',
         'compiler/util.h',
         'compiler/ValidateLimitations.cpp',
         'compiler/ValidateLimitations.h',
         'compiler/VariableInfo.cpp',
         'compiler/VariableInfo.h',
         'compiler/preprocessor/atom.c',
         'compiler/preprocessor/atom.h',
@@ -97,20 +102,24 @@
       'type': 'static_library',
       'dependencies': ['translator_common'],
       'include_dirs': [
         '.',
         '../include',
       ],
       'sources': [
         'compiler/CodeGenGLSL.cpp',
-        'compiler/ForLoopUnroll.cpp',
-        'compiler/ForLoopUnroll.h',
+        'compiler/OutputESSL.cpp',
+        'compiler/OutputESSL.h',        
+        'compiler/OutputGLSLBase.cpp',
+        'compiler/OutputGLSLBase.h',
         'compiler/OutputGLSL.cpp',
         'compiler/OutputGLSL.h',
+        'compiler/TranslatorESSL.cpp',
+        'compiler/TranslatorESSL.h',
         'compiler/TranslatorGLSL.cpp',
         'compiler/TranslatorGLSL.h',
         'compiler/VersionGLSL.cpp',
         'compiler/VersionGLSL.h',
       ],
     },
     {
       'target_name': 'translator_hlsl',
@@ -164,16 +173,17 @@
             'libGLESv2/Fence.cpp',
             'libGLESv2/Fence.h',
             'libGLESv2/Framebuffer.cpp',
             'libGLESv2/Framebuffer.h',
             'libGLESv2/HandleAllocator.cpp',
             'libGLESv2/HandleAllocator.h',
             'libGLESv2/libGLESv2.cpp',
             'libGLESv2/libGLESv2.def',
+            'libGLESv2/libGLESv2.rc',
             'libGLESv2/main.cpp',
             'libGLESv2/main.h',
             'libGLESv2/mathutil.h',
             'libGLESv2/Program.cpp',
             'libGLESv2/Program.h',
             'libGLESv2/RefCountObject.cpp',
             'libGLESv2/RefCountObject.h',
             'libGLESv2/Renderbuffer.cpp',
@@ -212,16 +222,17 @@
             'common/debug.h',
             'common/version.h',
             'libEGL/Config.cpp',
             'libEGL/Config.h',
             'libEGL/Display.cpp',
             'libEGL/Display.h',
             'libEGL/libEGL.cpp',
             'libEGL/libEGL.def',
+            'libEGL/libEGL.rc',
             'libEGL/main.cpp',
             'libEGL/main.h',
             'libEGL/Surface.cpp',
             'libEGL/Surface.h',
           ],
           'msvs_settings': {
             'VCLinkerTool': {
               'AdditionalLibraryDirectories': ['$(DXSDK_DIR)/lib/x86'],
--- a/gfx/angle/src/common/version.h
+++ b/gfx/angle/src/common/version.h
@@ -1,10 +1,10 @@
 #define MAJOR_VERSION 0
 #define MINOR_VERSION 0
 #define BUILD_VERSION 0
-#define BUILD_REVISION 686
+#define BUILD_REVISION 740
 
 #define STRINGIFY(x) #x
 #define MACRO_STRINGIFY(x) STRINGIFY(x)
 
 #define REVISION_STRING MACRO_STRINGIFY(BUILD_REVISION)
 #define VERSION_STRING MACRO_STRINGIFY(MAJOR_VERSION) "." MACRO_STRINGIFY(MINOR_VERSION) "." MACRO_STRINGIFY(BUILD_VERSION) "." MACRO_STRINGIFY(BUILD_REVISION)
--- a/gfx/angle/src/compiler/BaseTypes.h
+++ b/gfx/angle/src/compiler/BaseTypes.h
@@ -37,31 +37,33 @@ enum TBasicType
 {
     EbtVoid,
     EbtFloat,
     EbtInt,
     EbtBool,
     EbtGuardSamplerBegin,  // non type:  see implementation of IsSampler()
     EbtSampler2D,
     EbtSamplerCube,
+    EbtSamplerExternalOES,  // Only valid if OES_EGL_image_external exists.
     EbtGuardSamplerEnd,    // non type:  see implementation of IsSampler()
     EbtStruct,
     EbtAddress,            // should be deprecated??
 };
 
 inline const char* getBasicString(TBasicType t)
 {
     switch (t)
     {
     case EbtVoid:              return "void";              break;
     case EbtFloat:             return "float";             break;
     case EbtInt:               return "int";               break;
     case EbtBool:              return "bool";              break;
     case EbtSampler2D:         return "sampler2D";         break;
     case EbtSamplerCube:       return "samplerCube";       break;
+    case EbtSamplerExternalOES: return "samplerExternalOES"; break;
     case EbtStruct:            return "structure";         break;
     default:                   return "unknown type";
     }
 }
 
 inline bool IsSampler(TBasicType type)
 {
     return type > EbtGuardSamplerBegin && type < EbtGuardSamplerEnd;
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/BuiltInFunctionEmulator.cpp
@@ -0,0 +1,161 @@
+//
+// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/BuiltInFunctionEmulator.h"
+
+#include "compiler/SymbolTable.h"
+
+namespace {
+
+const char* kFunctionEmulationSource[] = {
+    "float webgl_normalize_emu(float a) { return normalize(a) * 1; }",
+    "vec2 webgl_normalize_emu(vec2 a) { return normalize(a) * 1; }",
+    "vec3 webgl_normalize_emu(vec3 a) { return normalize(a) * 1; }",
+    "vec4 webgl_normalize_emu(vec4 a) { return normalize(a) * 1; }",
+    "float webgl_abs_emu(float a) { float rt = abs(a); if (rt < 0.0) rt = 0.0;  return rt; }",
+    "vec2 webgl_abs_emu(vec2 a) { vec2 rt = abs(a); if (rt[0] < 0.0) rt[0] = 0.0;  return rt; }",
+    "vec3 webgl_abs_emu(vec3 a) { vec3 rt = abs(a); if (rt[0] < 0.0) rt[0] = 0.0;  return rt; }",
+    "vec4 webgl_abs_emu(vec4 a) { vec4 rt = abs(a); if (rt[0] < 0.0) rt[0] = 0.0;  return rt; }",
+    "float webgl_sign_emu(float a) { float rt = sign(a); if (rt > 1.0) rt = 1.0;  return rt; }",
+    "vec2 webgl_sign_emu(vec2 a) { float rt = sign(a); if (rt[0] > 1.0) rt[0] = 1.0;  return rt; }",
+    "vec3 webgl_sign_emu(vec3 a) { float rt = sign(a); if (rt[0] > 1.0) rt[0] = 1.0;  return rt; }",
+    "vec4 webgl_sign_emu(vec4 a) { float rt = sign(a); if (rt[0] > 1.0) rt[0] = 1.0;  return rt; }",
+};
+
+class BuiltInFunctionEmulationMarker : public TIntermTraverser {
+public:
+    BuiltInFunctionEmulationMarker(BuiltInFunctionEmulator& emulator)
+        : mEmulator(emulator)
+    {
+    }
+
+    virtual bool visitUnary(Visit visit, TIntermUnary* node)
+    {
+        if (visit == PreVisit) {
+            bool needToEmulate = mEmulator.SetFunctionCalled(
+                node->getOp(), node->getOperand()->getType());
+            if (needToEmulate)
+                node->setUseEmulatedFunction();
+        }
+        return true;
+    }
+
+private:
+    BuiltInFunctionEmulator& mEmulator;
+};
+
+}  // anonymous namepsace
+
+BuiltInFunctionEmulator::BuiltInFunctionEmulator()
+    : mFunctionGroupMask(TFunctionGroupAll)
+{
+}
+
+void BuiltInFunctionEmulator::SetFunctionGroupMask(
+    unsigned int functionGroupMask)
+{
+    mFunctionGroupMask = functionGroupMask;
+}
+
+bool BuiltInFunctionEmulator::SetFunctionCalled(
+    TOperator op, const TType& returnType)
+{
+    TBuiltInFunction function = IdentifyFunction(op, returnType);
+    if (function == TFunctionUnknown)
+        return false;
+    for (size_t i = 0; i < mFunctions.size(); ++i) {
+        if (mFunctions[i] == function)
+            return true;
+    }
+    switch (function) {
+        case TFunctionNormalize1:
+        case TFunctionNormalize2:
+        case TFunctionNormalize3:
+        case TFunctionNormalize4:
+            if (mFunctionGroupMask & TFunctionGroupNormalize) {
+                mFunctions.push_back(function);
+                return true;
+            }
+            break;
+        case TFunctionAbs1:
+        case TFunctionAbs2:
+        case TFunctionAbs3:
+        case TFunctionAbs4:
+            if (mFunctionGroupMask & TFunctionGroupAbs) {
+                mFunctions.push_back(function);
+                return true;
+            }
+            break;
+        case TFunctionSign1:
+        case TFunctionSign2:
+        case TFunctionSign3:
+        case TFunctionSign4:
+            if (mFunctionGroupMask & TFunctionGroupSign) {
+                mFunctions.push_back(function);
+                return true;
+            }
+            break;
+        default:
+            UNREACHABLE();
+            break;
+    }
+    return false;
+}
+
+void BuiltInFunctionEmulator::OutputEmulatedFunctionDefinition(
+    TInfoSinkBase& out, bool withPrecision) const
+{
+    if (mFunctions.size() == 0)
+        return;
+    out << "// BEGIN: Generated code for built-in function emulation\n\n";
+    if (withPrecision) {
+        out << "#if defined(GL_FRAGMENT_PRECISION_HIGH) && (GL_FRAGMENT_PRECISION_HIGH == 1)\n"
+            << "precision highp float;\n"
+            << "#else\n"
+            << "precision mediump float;\n"
+            << "#endif\n\n";
+    }
+    for (size_t i = 0; i < mFunctions.size(); ++i) {
+        out << kFunctionEmulationSource[mFunctions[i]] << "\n\n";
+    }
+    out << "// END: Generated code for built-in function emulation\n\n";
+}
+
+BuiltInFunctionEmulator::TBuiltInFunction
+BuiltInFunctionEmulator::IdentifyFunction(TOperator op, const TType& returnType)
+{
+    unsigned int function = TFunctionUnknown;
+    if (op == EOpNormalize)
+        function = TFunctionNormalize1;
+    else if (op == EOpAbs)
+        function = TFunctionAbs1;
+    else if (op == EOpSign)
+        function = TFunctionSign1;
+    else
+        return static_cast<TBuiltInFunction>(function);
+
+    if (returnType.isVector())
+        function += returnType.getNominalSize() - 1;
+    return static_cast<TBuiltInFunction>(function);
+}
+
+void BuiltInFunctionEmulator::MarkBuiltInFunctionsForEmulation(
+    TIntermNode* root)
+{
+    ASSERT(root);
+
+    BuiltInFunctionEmulationMarker marker(*this);
+    root->traverse(&marker);
+}
+
+//static
+TString BuiltInFunctionEmulator::GetEmulatedFunctionName(
+    const TString& name)
+{
+    ASSERT(name[name.length() - 1] == '(');
+    return "webgl_" + name.substr(0, name.length() - 1) + "_emu(";
+}
+
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/BuiltInFunctionEmulator.h
@@ -0,0 +1,86 @@
+//
+// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILIER_BUILT_IN_FUNCTION_EMULATOR_H_
+#define COMPILIER_BUILT_IN_FUNCTION_EMULATOR_H_
+
+#include "compiler/InfoSink.h"
+#include "compiler/intermediate.h"
+
+//
+// Built-in function groups.  We only list the ones that might need to be
+// emulated in certain os/drivers, assuming they are no more than 32.
+//
+enum TBuiltInFunctionGroup {
+    TFunctionGroupNormalize      = 1 << 0,
+    TFunctionGroupAbs            = 1 << 1,
+    TFunctionGroupSign           = 1 << 2,
+    TFunctionGroupAll            =
+        TFunctionGroupNormalize | TFunctionGroupAbs | TFunctionGroupSign
+};
+
+//
+// This class decides which built-in functions need to be replaced with the
+// emulated ones.
+// It's only a workaround for OpenGL driver bugs, and isn't needed in general.
+//
+class BuiltInFunctionEmulator {
+public:
+    BuiltInFunctionEmulator();
+
+    // functionGroupMask is a bitmap of TBuiltInFunctionGroup.
+    // We only emulate functions that are marked by this mask and are actually
+    // called in a given shader.
+    // By default the value is TFunctionGroupAll.
+    void SetFunctionGroupMask(unsigned int functionGroupMask);
+
+    // Records that a function is called by the shader and might needs to be
+    // emulated.  If the function's group is not in mFunctionGroupFilter, this
+    // becomes an no-op.
+    // Returns true if the function call needs to be replaced with an emulated
+    // one.
+    // TODO(zmo): for now, an operator and a return type is enough to identify
+    // the function we want to emulate.  Should make this more flexible to
+    // handle any functions.
+    bool SetFunctionCalled(TOperator op, const TType& returnType);
+
+    // Output function emulation definition.  This should be before any other
+    // shader source.
+    void OutputEmulatedFunctionDefinition(TInfoSinkBase& out, bool withPrecision) const;
+
+    void MarkBuiltInFunctionsForEmulation(TIntermNode* root);
+
+    // "name(" becomes "webgl_name_emu(".
+    static TString GetEmulatedFunctionName(const TString& name);
+
+private:
+    //
+    // Built-in functions.
+    //
+    enum TBuiltInFunction {
+        TFunctionNormalize1 = 0,  // float normalize(float);
+        TFunctionNormalize2,  // vec2 normalize(vec2);
+        TFunctionNormalize3,  // vec3 normalize(vec3);
+        TFunctionNormalize4,  // fec4 normalize(vec4);
+        TFunctionAbs1,  // float abs(float);
+        TFunctionAbs2,  // vec2 abs(vec2);
+        TFunctionAbs3,  // vec3 abs(vec3);
+        TFunctionAbs4,  // vec4 abs(vec4);
+        TFunctionSign1,  // float sign(float);
+        TFunctionSign2,  // vec2 sign(vec2);
+        TFunctionSign3,  // vec3 sign(vec3);
+        TFunctionSign4,  // vec4 sign(vec4);
+        TFunctionUnknown
+    };
+
+    // Same TODO as SetFunctionCalled.
+    TBuiltInFunction IdentifyFunction(TOperator op, const TType& returnType);
+
+    TVector<TBuiltInFunction> mFunctions;
+    unsigned int mFunctionGroupMask;  // a bitmap of TBuiltInFunctionGroup.
+};
+
+#endif  // COMPILIER_BUILT_IN_FUNCTION_EMULATOR_H_
--- a/gfx/angle/src/compiler/CodeGenGLSL.cpp
+++ b/gfx/angle/src/compiler/CodeGenGLSL.cpp
@@ -1,24 +1,33 @@
 //
 // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 #include "compiler/TranslatorGLSL.h"
+#include "compiler/TranslatorESSL.h"
 
 //
 // This function must be provided to create the actual
 // compile object used by higher level code.  It returns
 // a subclass of TCompiler.
 //
-TCompiler* ConstructCompiler(ShShaderType type, ShShaderSpec spec)
+TCompiler* ConstructCompiler(
+    ShShaderType type, ShShaderSpec spec, ShShaderOutput output)
 {
-    return new TranslatorGLSL(type, spec);
+    switch (output) {
+      case SH_GLSL_OUTPUT:
+        return new TranslatorGLSL(type, spec);
+      case SH_ESSL_OUTPUT:
+        return new TranslatorESSL(type, spec);
+      default:
+        return NULL;
+    }
 }
 
 //
 // Delete the compiler made by ConstructCompiler
 //
 void DeleteCompiler(TCompiler* compiler)
 {
     delete compiler;
--- a/gfx/angle/src/compiler/CodeGenHLSL.cpp
+++ b/gfx/angle/src/compiler/CodeGenHLSL.cpp
@@ -6,19 +6,25 @@
 
 #include "compiler/TranslatorHLSL.h"
 
 //
 // This function must be provided to create the actual
 // compile object used by higher level code.  It returns
 // a subclass of TCompiler.
 //
-TCompiler* ConstructCompiler(ShShaderType type, ShShaderSpec spec)
+TCompiler* ConstructCompiler(
+    ShShaderType type, ShShaderSpec spec, ShShaderOutput output)
 {
-    return new TranslatorHLSL(type, spec);
+  switch (output) {
+    case SH_HLSL_OUTPUT:
+      return new TranslatorHLSL(type, spec);
+    default:
+      return NULL;
+  }
 }
 
 //
 // Delete the compiler made by ConstructCompiler
 //
 void DeleteCompiler(TCompiler* compiler)
 {
     delete compiler;
--- a/gfx/angle/src/compiler/Compiler.cpp
+++ b/gfx/angle/src/compiler/Compiler.cpp
@@ -1,30 +1,35 @@
 //
 // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
+#include "compiler/BuiltInFunctionEmulator.h"
 #include "compiler/DetectRecursion.h"
+#include "compiler/ForLoopUnroll.h"
 #include "compiler/Initialize.h"
 #include "compiler/ParseHelper.h"
 #include "compiler/ShHandle.h"
 #include "compiler/ValidateLimitations.h"
 #include "compiler/MapLongVariableNames.h"
 
 namespace {
 bool InitializeSymbolTable(
     const TBuiltInStrings& builtInStrings,
     ShShaderType type, ShShaderSpec spec, const ShBuiltInResources& resources,
     TInfoSink& infoSink, TSymbolTable& symbolTable)
 {
     TIntermediate intermediate(infoSink);
     TExtensionBehavior extBehavior;
-    TParseContext parseContext(symbolTable, extBehavior, intermediate, type, spec, 0, NULL, infoSink);
+    InitExtensionBehavior(resources, extBehavior);
+    // The builtins deliberately don't specify precisions for the function
+    // arguments and return types. For that reason we don't try to check them.
+    TParseContext parseContext(symbolTable, extBehavior, intermediate, type, spec, 0, false, NULL, infoSink);
 
     GlobalParseContext = &parseContext;
 
     assert(symbolTable.isEmpty());       
     //
     // Parse the built-ins.  This should only happen once per
     // language symbol table.
     //
@@ -123,17 +128,17 @@ bool TCompiler::compile(const char* cons
     if (compileOptions & SH_SOURCE_PATH)
     {
         sourcePath = shaderStrings[0];
         ++firstSource;
     }
 
     TIntermediate intermediate(infoSink);
     TParseContext parseContext(symbolTable, extensionBehavior, intermediate,
-                               shaderType, shaderSpec, compileOptions,
+                               shaderType, shaderSpec, compileOptions, true,
                                sourcePath, infoSink);
     GlobalParseContext = &parseContext;
 
     // We preserve symbols at the built-in level from compile-to-compile.
     // Start pushing the user-defined symbols at global level.
     symbolTable.push();
     if (!symbolTable.atGlobalLevel())
         infoSink.info.message(EPrefixInternalError, "Wrong symbol table level");
@@ -147,16 +152,24 @@ bool TCompiler::compile(const char* cons
         success = intermediate.postProcess(root);
 
         if (success)
             success = detectRecursion(root);
 
         if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING))
             success = validateLimitations(root);
 
+        // Unroll for-loop markup needs to happen after validateLimitations pass.
+        if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX))
+            ForLoopUnroll::MarkForLoopsWithIntegerIndicesForUnrolling(root);
+
+        // Built-in function emulation needs to happen after validateLimitations pass.
+        if (success && (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS))
+            builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(root);
+
         // Call mapLongVariableNames() before collectAttribsUniforms() so in
         // collectAttribsUniforms() we already have the mapped symbol names and
         // we could composite mapped and original variable names.
         if (success && (compileOptions & SH_MAP_LONG_VARIABLE_NAMES))
             mapLongVariableNames(root);
 
         if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS))
             collectAttribsUniforms(root);
@@ -233,8 +246,18 @@ void TCompiler::mapLongVariableNames(TIn
     MapLongVariableNames map(varyingLongNameMap);
     root->traverse(&map);
 }
 
 int TCompiler::getMappedNameMaxLength() const
 {
     return MAX_IDENTIFIER_NAME_SIZE + 1;
 }
+
+const TExtensionBehavior& TCompiler::getExtensionBehavior() const
+{
+    return extensionBehavior;
+}
+
+const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const
+{
+    return builtInFunctionEmulator;
+}
--- a/gfx/angle/src/compiler/DetectRecursion.cpp
+++ b/gfx/angle/src/compiler/DetectRecursion.cpp
@@ -59,39 +59,16 @@ DetectRecursion::DetectRecursion()
 }
 
 DetectRecursion::~DetectRecursion()
 {
     for (int i = 0; i < functions.size(); ++i)
         delete functions[i];
 }
 
-void DetectRecursion::visitSymbol(TIntermSymbol*)
-{
-}
-
-void DetectRecursion::visitConstantUnion(TIntermConstantUnion*)
-{
-}
-
-bool DetectRecursion::visitBinary(Visit, TIntermBinary*)
-{
-    return true;
-}
-
-bool DetectRecursion::visitUnary(Visit, TIntermUnary*)
-{
-    return true;
-}
-
-bool DetectRecursion::visitSelection(Visit, TIntermSelection*)
-{
-    return true;
-}
-
 bool DetectRecursion::visitAggregate(Visit visit, TIntermAggregate* node)
 {
     switch (node->getOp())
     {
         case EOpPrototype:
             // Function declaration.
             // Don't add FunctionNode here because node->getName() is the
             // unmangled function name.
@@ -121,26 +98,16 @@ bool DetectRecursion::visitAggregate(Vis
             break;
         }
         default:
             break;
     }
     return true;
 }
 
-bool DetectRecursion::visitLoop(Visit, TIntermLoop*)
-{
-    return true;
-}
-
-bool DetectRecursion::visitBranch(Visit, TIntermBranch*)
-{
-    return true;
-}
-
 DetectRecursion::ErrorCode DetectRecursion::detectRecursion()
 {
     FunctionNode* main = findFunctionByName("main(");
     if (main == NULL)
         return kErrorMissingMain;
     if (main->detectRecursion())
         return kErrorRecursion;
     return kErrorNone;
--- a/gfx/angle/src/compiler/DetectRecursion.h
+++ b/gfx/angle/src/compiler/DetectRecursion.h
@@ -19,24 +19,17 @@ public:
         kErrorMissingMain,
         kErrorRecursion,
         kErrorNone
     };
 
     DetectRecursion();
     ~DetectRecursion();
 
-    virtual void visitSymbol(TIntermSymbol*);
-    virtual void visitConstantUnion(TIntermConstantUnion*);
-    virtual bool visitBinary(Visit, TIntermBinary*);
-    virtual bool visitUnary(Visit, TIntermUnary*);
-    virtual bool visitSelection(Visit, TIntermSelection*);
     virtual bool visitAggregate(Visit, TIntermAggregate*);
-    virtual bool visitLoop(Visit, TIntermLoop*);
-    virtual bool visitBranch(Visit, TIntermBranch*);
 
     ErrorCode detectRecursion();
 
 private:
     class FunctionNode {
     public:
         FunctionNode(const TString& fname);
 
--- a/gfx/angle/src/compiler/ExtensionBehavior.h
+++ b/gfx/angle/src/compiler/ExtensionBehavior.h
@@ -8,14 +8,31 @@
 #define _EXTENSION_BEHAVIOR_INCLUDED_
 
 #include "compiler/Common.h"
 
 typedef enum {
     EBhRequire,
     EBhEnable,
     EBhWarn,
-    EBhDisable
+    EBhDisable,
+    EBhUndefined,
 } TBehavior;
 
+inline const char* getBehaviorString(TBehavior b)
+{
+    switch(b) {
+      case EBhRequire:
+        return "require";
+      case EBhEnable:
+        return "enable";
+      case EBhWarn:
+        return "warn";
+      case EBhDisable:
+        return "disable";
+      default:
+        return NULL;
+    }
+}
+
 typedef TMap<TString, TBehavior> TExtensionBehavior;
 
 #endif // _EXTENSION_TABLE_INCLUDED_
--- a/gfx/angle/src/compiler/ForLoopUnroll.cpp
+++ b/gfx/angle/src/compiler/ForLoopUnroll.cpp
@@ -1,16 +1,49 @@
 //
 // Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 #include "compiler/ForLoopUnroll.h"
 
+namespace {
+
+class IntegerForLoopUnrollMarker : public TIntermTraverser {
+public:
+
+    virtual bool visitLoop(Visit, TIntermLoop* node)
+    {
+        // This is called after ValidateLimitations pass, so all the ASSERT
+        // should never fail.
+        // See ValidateLimitations::validateForLoopInit().
+        ASSERT(node);
+        ASSERT(node->getType() == ELoopFor);
+        ASSERT(node->getInit());
+        TIntermAggregate* decl = node->getInit()->getAsAggregate();
+        ASSERT(decl && decl->getOp() == EOpDeclaration);
+        TIntermSequence& declSeq = decl->getSequence();
+        ASSERT(declSeq.size() == 1);
+        TIntermBinary* declInit = declSeq[0]->getAsBinaryNode();
+        ASSERT(declInit && declInit->getOp() == EOpInitialize);
+        ASSERT(declInit->getLeft());
+        TIntermSymbol* symbol = declInit->getLeft()->getAsSymbolNode();
+        ASSERT(symbol);
+        TBasicType type = symbol->getBasicType();
+        ASSERT(type == EbtInt || type == EbtFloat);
+        if (type == EbtInt)
+            node->setUnrollFlag(true);
+        return true;
+    }
+
+};
+
+}  // anonymous namepsace
+
 void ForLoopUnroll::FillLoopIndexInfo(TIntermLoop* node, TLoopIndexInfo& info)
 {
     ASSERT(node->getType() == ELoopFor);
     ASSERT(node->getUnrollFlag());
 
     TIntermNode* init = node->getInit();
     ASSERT(init != NULL);
     TIntermAggregate* decl = init->getAsAggregate();
@@ -104,16 +137,26 @@ void ForLoopUnroll::Push(TLoopIndexInfo&
     mLoopIndexStack.push_back(info);
 }
 
 void ForLoopUnroll::Pop()
 {
     mLoopIndexStack.pop_back();
 }
 
+// static
+void ForLoopUnroll::MarkForLoopsWithIntegerIndicesForUnrolling(
+    TIntermNode* root)
+{
+    ASSERT(root);
+
+    IntegerForLoopUnrollMarker marker;
+    root->traverse(&marker);
+}
+
 int ForLoopUnroll::getLoopIncrement(TIntermLoop* node)
 {
     TIntermNode* expr = node->getExpression();
     ASSERT(expr != NULL);
     // for expression has one of the following forms:
     //     loop_index++
     //     loop_index--
     //     loop_index += constant_expression
--- a/gfx/angle/src/compiler/ForLoopUnroll.h
+++ b/gfx/angle/src/compiler/ForLoopUnroll.h
@@ -31,16 +31,18 @@ public:
     bool NeedsToReplaceSymbolWithValue(TIntermSymbol* symbol);
 
     // Return the current value of a given loop index symbol.
     int GetLoopIndexValue(TIntermSymbol* symbol);
 
     void Push(TLoopIndexInfo& info);
     void Pop();
 
+    static void MarkForLoopsWithIntegerIndicesForUnrolling(TIntermNode* root);
+
 private:
     int getLoopIncrement(TIntermLoop* node);
 
     int evaluateIntConstant(TIntermConstantUnion* node);
 
     TVector<TLoopIndexInfo> mLoopIndexStack;
 };
 
--- a/gfx/angle/src/compiler/Initialize.cpp
+++ b/gfx/angle/src/compiler/Initialize.cpp
@@ -358,16 +358,22 @@ static TString BuiltInFunctionsVertex(co
     s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord);"));
     s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord);"));
 
     s.append(TString("vec4 texture2DLod(sampler2D sampler, vec2 coord, float lod);"));
     s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec3 coord, float lod);"));
     s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec4 coord, float lod);"));
     s.append(TString("vec4 textureCubeLod(samplerCube sampler, vec3 coord, float lod);"));
 
+    if (resources.OES_EGL_image_external) {
+        s.append(TString("vec4 texture2D(samplerExternalOES sampler, vec2 coord);"));
+        s.append(TString("vec4 texture2DProj(samplerExternalOES sampler, vec3 coord);"));
+        s.append(TString("vec4 texture2DProj(samplerExternalOES sampler, vec4 coord);"));
+    }
+
     return s;
 }
 
 //============================================================================
 //
 // Prototypes for built-in functions seen by fragment shaders only.
 //
 //============================================================================
@@ -383,16 +389,22 @@ static TString BuiltInFunctionsFragment(
     s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord);"));
     s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord);"));
 
     s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord, float bias);"));
     s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord, float bias);"));
     s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord, float bias);"));
     s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord, float bias);"));
 
+    if (resources.OES_EGL_image_external) {
+        s.append(TString("vec4 texture2D(samplerExternalOES sampler, vec2 coord);"));
+        s.append(TString("vec4 texture2DProj(samplerExternalOES sampler, vec3 coord);"));
+        s.append(TString("vec4 texture2DProj(samplerExternalOES sampler, vec4 coord);"));
+    }
+
     if (resources.OES_standard_derivatives) {
         s.append(TString("float dFdx(float p);"));
         s.append(TString("vec2  dFdx(vec2  p);"));
         s.append(TString("vec3  dFdx(vec3  p);"));
         s.append(TString("vec4  dFdx(vec4  p);"));
 
         s.append(TString("float dFdy(float p);"));
         s.append(TString("vec2  dFdy(vec2  p);"));
@@ -620,10 +632,12 @@ void IdentifyBuiltIns(ShShaderType type,
     default: break;
     }
 }
 
 void InitExtensionBehavior(const ShBuiltInResources& resources,
                            TExtensionBehavior& extBehavior)
 {
     if (resources.OES_standard_derivatives)
-        extBehavior["GL_OES_standard_derivatives"] = EBhDisable;
+        extBehavior["GL_OES_standard_derivatives"] = EBhUndefined;
+    if (resources.OES_EGL_image_external)
+        extBehavior["GL_OES_EGL_image_external"] = EBhUndefined;
 }
--- a/gfx/angle/src/compiler/MapLongVariableNames.cpp
+++ b/gfx/angle/src/compiler/MapLongVariableNames.cpp
@@ -43,47 +43,20 @@ void MapLongVariableNames::visitSymbol(T
           default:
             symbol->setSymbol(
                 mapLongName(symbol->getId(), symbol->getSymbol(), false));
             break;
         };
     }
 }
 
-void MapLongVariableNames::visitConstantUnion(TIntermConstantUnion*)
-{
-}
-
-bool MapLongVariableNames::visitBinary(Visit, TIntermBinary*)
-{
-    return true;
-}
-
-bool MapLongVariableNames::visitUnary(Visit, TIntermUnary*)
-{
-    return true;
-}
-
-bool MapLongVariableNames::visitSelection(Visit, TIntermSelection*)
+bool MapLongVariableNames::visitLoop(Visit, TIntermLoop* node)
 {
-    return true;
-}
-
-bool MapLongVariableNames::visitAggregate(Visit, TIntermAggregate* node)
-{
-    return true;
-}
-
-bool MapLongVariableNames::visitLoop(Visit, TIntermLoop*)
-{
-    return true;
-}
-
-bool MapLongVariableNames::visitBranch(Visit, TIntermBranch*)
-{
+    if (node->getInit())
+        node->getInit()->traverse(this);
     return true;
 }
 
 TString MapLongVariableNames::mapVaryingLongName(const TString& name)
 {
     TMap<TString, TString>::const_iterator it = mVaryingLongNameMap.find(name);
     if (it != mVaryingLongNameMap.end())
         return (*it).second;
--- a/gfx/angle/src/compiler/MapLongVariableNames.h
+++ b/gfx/angle/src/compiler/MapLongVariableNames.h
@@ -17,23 +17,17 @@
 
 // Traverses intermediate tree to map attributes and uniforms names that are
 // longer than MAX_IDENTIFIER_NAME_SIZE to MAX_IDENTIFIER_NAME_SIZE.
 class MapLongVariableNames : public TIntermTraverser {
 public:
     MapLongVariableNames(TMap<TString, TString>& varyingLongNameMap);
 
     virtual void visitSymbol(TIntermSymbol*);
-    virtual void visitConstantUnion(TIntermConstantUnion*);
-    virtual bool visitBinary(Visit, TIntermBinary*);
-    virtual bool visitUnary(Visit, TIntermUnary*);
-    virtual bool visitSelection(Visit, TIntermSelection*);
-    virtual bool visitAggregate(Visit, TIntermAggregate*);
     virtual bool visitLoop(Visit, TIntermLoop*);
-    virtual bool visitBranch(Visit, TIntermBranch*);
 
 private:
     TString mapVaryingLongName(const TString& name);
 
     TMap<TString, TString>& mVaryingLongNameMap;
 };
 
 #endif  // COMPILER_MAP_LONG_VARIABLE_NAMES_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/OutputESSL.cpp
@@ -0,0 +1,22 @@
+//
+// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/OutputESSL.h"
+
+TOutputESSL::TOutputESSL(TInfoSinkBase& objSink)
+    : TOutputGLSLBase(objSink)
+{
+}
+
+bool TOutputESSL::writeVariablePrecision(TPrecision precision)
+{
+    if (precision == EbpUndefined)
+        return false;
+
+    TInfoSinkBase& out = objSink();
+    out << getPrecisionString(precision);
+    return true;
+}
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/OutputESSL.h
@@ -0,0 +1,21 @@
+//
+// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef CROSSCOMPILERGLSL_OUTPUTESSL_H_
+#define CROSSCOMPILERGLSL_OUTPUTESSL_H_
+
+#include "compiler/OutputGLSLBase.h"
+
+class TOutputESSL : public TOutputGLSLBase
+{
+public:
+    TOutputESSL(TInfoSinkBase& objSink);
+
+protected:
+    virtual bool writeVariablePrecision(TPrecision precision);
+};
+
+#endif  // CROSSCOMPILERGLSL_OUTPUTESSL_H_
--- a/gfx/angle/src/compiler/OutputGLSL.cpp
+++ b/gfx/angle/src/compiler/OutputGLSL.cpp
@@ -1,710 +1,17 @@
 //
 // Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 #include "compiler/OutputGLSL.h"
-#include "compiler/compilerdebug.h"
-
-namespace
-{
-TString getTypeName(const TType& type)
-{
-    TInfoSinkBase out;
-    if (type.isMatrix())
-    {
-        out << "mat";
-        out << type.getNominalSize();
-    }
-    else if (type.isVector())
-    {
-        switch (type.getBasicType())
-        {
-            case EbtFloat: out << "vec"; break;
-            case EbtInt: out << "ivec"; break;
-            case EbtBool: out << "bvec"; break;
-            default: UNREACHABLE(); break;
-        }
-        out << type.getNominalSize();
-    }
-    else
-    {
-        if (type.getBasicType() == EbtStruct)
-            out << type.getTypeName();
-        else
-            out << type.getBasicString();
-    }
-    return TString(out.c_str());
-}
-
-TString arrayBrackets(const TType& type)
-{
-    ASSERT(type.isArray());
-    TInfoSinkBase out;
-    out << "[" << type.getArraySize() << "]";
-    return TString(out.c_str());
-}
-
-bool isSingleStatement(TIntermNode* node) {
-    if (const TIntermAggregate* aggregate = node->getAsAggregate())
-    {
-        return (aggregate->getOp() != EOpFunction) &&
-               (aggregate->getOp() != EOpSequence);
-    }
-    else if (const TIntermSelection* selection = node->getAsSelectionNode())
-    {
-        // Ternary operators are usually part of an assignment operator.
-        // This handles those rare cases in which they are all by themselves.
-        return selection->usesTernaryOperator();
-    }
-    else if (node->getAsLoopNode())
-    {
-        return false;
-    }
-    return true;
-}
-}  // namespace
 
 TOutputGLSL::TOutputGLSL(TInfoSinkBase& objSink)
-    : TIntermTraverser(true, true, true),
-      mObjSink(objSink),
-      mDeclaringVariables(false)
+    : TOutputGLSLBase(objSink)
 {
 }
 
-void TOutputGLSL::writeTriplet(Visit visit, const char* preStr, const char* inStr, const char* postStr)
-{
-    TInfoSinkBase& out = objSink();
-    if (visit == PreVisit && preStr)
-    {
-        out << preStr;
-    }
-    else if (visit == InVisit && inStr)
-    {
-        out << inStr;
-    }
-    else if (visit == PostVisit && postStr)
-    {
-        out << postStr;
-    }
-}
-
-void TOutputGLSL::writeVariableType(const TType& type)
-{
-    TInfoSinkBase& out = objSink();
-    TQualifier qualifier = type.getQualifier();
-    // TODO(alokp): Validate qualifier for variable declarations.
-    if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal))
-        out << type.getQualifierString() << " ";
-
-    // Declare the struct if we have not done so already.
-    if ((type.getBasicType() == EbtStruct) &&
-        (mDeclaredStructs.find(type.getTypeName()) == mDeclaredStructs.end()))
-    {
-        out << "struct " << type.getTypeName() << "{\n";
-        const TTypeList* structure = type.getStruct();
-        ASSERT(structure != NULL);
-        for (size_t i = 0; i < structure->size(); ++i)
-        {
-            const TType* fieldType = (*structure)[i].type;
-            ASSERT(fieldType != NULL);
-            out << getTypeName(*fieldType) << " " << fieldType->getFieldName();
-            if (fieldType->isArray())
-                out << arrayBrackets(*fieldType);
-            out << ";\n";
-        }
-        out << "}";
-        mDeclaredStructs.insert(type.getTypeName());
-    }
-    else
-    {
-        out << getTypeName(type);
-    }
-}
-
-void TOutputGLSL::writeFunctionParameters(const TIntermSequence& args)
-{
-    TInfoSinkBase& out = objSink();
-    for (TIntermSequence::const_iterator iter = args.begin();
-         iter != args.end(); ++iter)
-    {
-        const TIntermSymbol* arg = (*iter)->getAsSymbolNode();
-        ASSERT(arg != NULL);
-
-        const TType& type = arg->getType();
-        TQualifier qualifier = type.getQualifier();
-        // TODO(alokp): Validate qualifier for function arguments.
-        if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal))
-            out << type.getQualifierString() << " ";
-
-        out << getTypeName(type);
-
-        const TString& name = arg->getSymbol();
-        if (!name.empty())
-            out << " " << name;
-        if (type.isArray())
-            out << arrayBrackets(type);
-
-        // Put a comma if this is not the last argument.
-        if (iter != args.end() - 1)
-            out << ", ";
-    }
-}
-
-const ConstantUnion* TOutputGLSL::writeConstantUnion(const TType& type,
-                                                     const ConstantUnion* pConstUnion)
-{
-    TInfoSinkBase& out = objSink();
-
-    if (type.getBasicType() == EbtStruct)
-    {
-        out << type.getTypeName() << "(";
-        const TTypeList* structure = type.getStruct();
-        ASSERT(structure != NULL);
-        for (size_t i = 0; i < structure->size(); ++i)
-        {
-            const TType* fieldType = (*structure)[i].type;
-            ASSERT(fieldType != NULL);
-            pConstUnion = writeConstantUnion(*fieldType, pConstUnion);
-            if (i != structure->size() - 1) out << ", ";
-        }
-        out << ")";
-    }
-    else
-    {
-        int size = type.getObjectSize();
-        bool writeType = size > 1;
-        if (writeType) out << getTypeName(type) << "(";
-        for (int i = 0; i < size; ++i, ++pConstUnion)
-        {
-            switch (pConstUnion->getType())
-            {
-                case EbtFloat: out << pConstUnion->getFConst(); break;
-                case EbtInt: out << pConstUnion->getIConst(); break;
-                case EbtBool: out << pConstUnion->getBConst(); break;
-                default: UNREACHABLE();
-            }
-            if (i != size - 1) out << ", ";
-        }
-        if (writeType) out << ")";
-    }
-    return pConstUnion;
-}
-
-void TOutputGLSL::visitSymbol(TIntermSymbol* node)
-{
-    TInfoSinkBase& out = objSink();
-    if (mLoopUnroll.NeedsToReplaceSymbolWithValue(node))
-        out << mLoopUnroll.GetLoopIndexValue(node);
-    else
-        out << node->getSymbol();
-
-    if (mDeclaringVariables && node->getType().isArray())
-        out << arrayBrackets(node->getType());
-}
-
-void TOutputGLSL::visitConstantUnion(TIntermConstantUnion* node)
-{
-    writeConstantUnion(node->getType(), node->getUnionArrayPointer());
-}
-
-bool TOutputGLSL::visitBinary(Visit visit, TIntermBinary* node)
+bool TOutputGLSL::writeVariablePrecision(TPrecision)
 {
-    bool visitChildren = true;
-    TInfoSinkBase& out = objSink();
-    switch (node->getOp())
-    {
-        case EOpInitialize:
-            if (visit == InVisit)
-            {
-                out << " = ";
-                // RHS of initialize is not being declared.
-                mDeclaringVariables = false;
-            }
-            break;
-        case EOpAssign: writeTriplet(visit, "(", " = ", ")"); break;
-        case EOpAddAssign: writeTriplet(visit, "(", " += ", ")"); break;
-        case EOpSubAssign: writeTriplet(visit, "(", " -= ", ")"); break;
-        case EOpDivAssign: writeTriplet(visit, "(", " /= ", ")"); break;
-        // Notice the fall-through.
-        case EOpMulAssign: 
-        case EOpVectorTimesMatrixAssign:
-        case EOpVectorTimesScalarAssign:
-        case EOpMatrixTimesScalarAssign:
-        case EOpMatrixTimesMatrixAssign:
-            writeTriplet(visit, "(", " *= ", ")");
-            break;
-
-        case EOpIndexDirect:
-        case EOpIndexIndirect:
-            writeTriplet(visit, NULL, "[", "]");
-            break;
-        case EOpIndexDirectStruct:
-            if (visit == InVisit)
-            {
-                out << ".";
-                // TODO(alokp): ASSERT
-                out << node->getType().getFieldName();
-                visitChildren = false;
-            }
-            break;
-        case EOpVectorSwizzle:
-            if (visit == InVisit)
-            {
-                out << ".";
-                TIntermAggregate* rightChild = node->getRight()->getAsAggregate();
-                TIntermSequence& sequence = rightChild->getSequence();
-                for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); ++sit)
-                {
-                    TIntermConstantUnion* element = (*sit)->getAsConstantUnion();
-                    ASSERT(element->getBasicType() == EbtInt);
-                    ASSERT(element->getNominalSize() == 1);
-                    const ConstantUnion& data = element->getUnionArrayPointer()[0];
-                    ASSERT(data.getType() == EbtInt);
-                    switch (data.getIConst())
-                    {
-                        case 0: out << "x"; break;
-                        case 1: out << "y"; break;
-                        case 2: out << "z"; break;
-                        case 3: out << "w"; break;
-                        default: UNREACHABLE(); break;
-                    }
-                }
-                visitChildren = false;
-            }
-            break;
-
-        case EOpAdd: writeTriplet(visit, "(", " + ", ")"); break;
-        case EOpSub: writeTriplet(visit, "(", " - ", ")"); break;
-        case EOpMul: writeTriplet(visit, "(", " * ", ")"); break;
-        case EOpDiv: writeTriplet(visit, "(", " / ", ")"); break;
-        case EOpMod: UNIMPLEMENTED(); break;
-        case EOpEqual: writeTriplet(visit, "(", " == ", ")"); break;
-        case EOpNotEqual: writeTriplet(visit, "(", " != ", ")"); break;
-        case EOpLessThan: writeTriplet(visit, "(", " < ", ")"); break;
-        case EOpGreaterThan: writeTriplet(visit, "(", " > ", ")"); break;
-        case EOpLessThanEqual: writeTriplet(visit, "(", " <= ", ")"); break;
-        case EOpGreaterThanEqual: writeTriplet(visit, "(", " >= ", ")"); break;
-
-        // Notice the fall-through.
-        case EOpVectorTimesScalar:
-        case EOpVectorTimesMatrix:
-        case EOpMatrixTimesVector:
-        case EOpMatrixTimesScalar:
-        case EOpMatrixTimesMatrix:
-            writeTriplet(visit, "(", " * ", ")");
-            break;
-
-        case EOpLogicalOr: writeTriplet(visit, "(", " || ", ")"); break;
-        case EOpLogicalXor: writeTriplet(visit, "(", " ^^ ", ")"); break;
-        case EOpLogicalAnd: writeTriplet(visit, "(", " && ", ")"); break;
-        default: UNREACHABLE(); break;
-    }
-
-    return visitChildren;
-}
-
-bool TOutputGLSL::visitUnary(Visit visit, TIntermUnary* node)
-{
-    switch (node->getOp())
-    {
-        case EOpNegative: writeTriplet(visit, "(-", NULL, ")"); break;
-        case EOpVectorLogicalNot: writeTriplet(visit, "not(", NULL, ")"); break;
-        case EOpLogicalNot: writeTriplet(visit, "(!", NULL, ")"); break;
-
-        case EOpPostIncrement: writeTriplet(visit, "(", NULL, "++)"); break;
-        case EOpPostDecrement: writeTriplet(visit, "(", NULL, "--)"); break;
-        case EOpPreIncrement: writeTriplet(visit, "(++", NULL, ")"); break;
-        case EOpPreDecrement: writeTriplet(visit, "(--", NULL, ")"); break;
-
-        case EOpConvIntToBool:
-        case EOpConvFloatToBool:
-            switch (node->getOperand()->getType().getNominalSize())
-            {
-                case 1: writeTriplet(visit, "bool(", NULL, ")");  break;
-                case 2: writeTriplet(visit, "bvec2(", NULL, ")"); break;
-                case 3: writeTriplet(visit, "bvec3(", NULL, ")"); break;
-                case 4: writeTriplet(visit, "bvec4(", NULL, ")"); break;
-                default: UNREACHABLE();
-            }
-            break;
-        case EOpConvBoolToFloat:
-        case EOpConvIntToFloat:
-            switch (node->getOperand()->getType().getNominalSize())
-            {
-                case 1: writeTriplet(visit, "float(", NULL, ")");  break;
-                case 2: writeTriplet(visit, "vec2(", NULL, ")"); break;
-                case 3: writeTriplet(visit, "vec3(", NULL, ")"); break;
-                case 4: writeTriplet(visit, "vec4(", NULL, ")"); break;
-                default: UNREACHABLE();
-            }
-            break;
-        case EOpConvFloatToInt:
-        case EOpConvBoolToInt:
-            switch (node->getOperand()->getType().getNominalSize())
-            {
-                case 1: writeTriplet(visit, "int(", NULL, ")");  break;
-                case 2: writeTriplet(visit, "ivec2(", NULL, ")"); break;
-                case 3: writeTriplet(visit, "ivec3(", NULL, ")"); break;
-                case 4: writeTriplet(visit, "ivec4(", NULL, ")"); break;
-                default: UNREACHABLE();
-            }
-            break;
-
-        case EOpRadians: writeTriplet(visit, "radians(", NULL, ")"); break;
-        case EOpDegrees: writeTriplet(visit, "degrees(", NULL, ")"); break;
-        case EOpSin: writeTriplet(visit, "sin(", NULL, ")"); break;
-        case EOpCos: writeTriplet(visit, "cos(", NULL, ")"); break;
-        case EOpTan: writeTriplet(visit, "tan(", NULL, ")"); break;
-        case EOpAsin: writeTriplet(visit, "asin(", NULL, ")"); break;
-        case EOpAcos: writeTriplet(visit, "acos(", NULL, ")"); break;
-        case EOpAtan: writeTriplet(visit, "atan(", NULL, ")"); break;
-
-        case EOpExp: writeTriplet(visit, "exp(", NULL, ")"); break;
-        case EOpLog: writeTriplet(visit, "log(", NULL, ")"); break;
-        case EOpExp2: writeTriplet(visit, "exp2(", NULL, ")"); break;
-        case EOpLog2: writeTriplet(visit, "log2(", NULL, ")"); break;
-        case EOpSqrt: writeTriplet(visit, "sqrt(", NULL, ")"); break;
-        case EOpInverseSqrt: writeTriplet(visit, "inversesqrt(", NULL, ")"); break;
-
-        case EOpAbs: writeTriplet(visit, "abs(", NULL, ")"); break;
-        case EOpSign: writeTriplet(visit, "sign(", NULL, ")"); break;
-        case EOpFloor: writeTriplet(visit, "floor(", NULL, ")"); break;
-        case EOpCeil: writeTriplet(visit, "ceil(", NULL, ")"); break;
-        case EOpFract: writeTriplet(visit, "fract(", NULL, ")"); break;
-
-        case EOpLength: writeTriplet(visit, "length(", NULL, ")"); break;
-        case EOpNormalize: writeTriplet(visit, "normalize(", NULL, ")"); break;
-
-        case EOpDFdx: writeTriplet(visit, "dFdx(", NULL, ")"); break;
-        case EOpDFdy: writeTriplet(visit, "dFdy(", NULL, ")"); break;
-        case EOpFwidth: writeTriplet(visit, "fwidth(", NULL, ")"); break;
-
-        case EOpAny: writeTriplet(visit, "any(", NULL, ")"); break;
-        case EOpAll: writeTriplet(visit, "all(", NULL, ")"); break;
-
-        default: UNREACHABLE(); break;
-    }
-
-    return true;
-}
-
-bool TOutputGLSL::visitSelection(Visit visit, TIntermSelection* node)
-{
-    TInfoSinkBase& out = objSink();
-
-    if (node->usesTernaryOperator())
-    {
-        // Notice two brackets at the beginning and end. The outer ones
-        // encapsulate the whole ternary expression. This preserves the
-        // order of precedence when ternary expressions are used in a
-        // compound expression, i.e., c = 2 * (a < b ? 1 : 2).
-        out << "((";
-        node->getCondition()->traverse(this);
-        out << ") ? (";
-        node->getTrueBlock()->traverse(this);
-        out << ") : (";
-        node->getFalseBlock()->traverse(this);
-        out << "))";
-    }
-    else
-    {
-        out << "if (";
-        node->getCondition()->traverse(this);
-        out << ")\n";
-
-        incrementDepth();
-        visitCodeBlock(node->getTrueBlock());
-
-        if (node->getFalseBlock())
-        {
-            out << "else\n";
-            visitCodeBlock(node->getFalseBlock());
-        }
-        decrementDepth();
-    }
     return false;
 }
-
-bool TOutputGLSL::visitAggregate(Visit visit, TIntermAggregate* node)
-{
-    bool visitChildren = true;
-    TInfoSinkBase& out = objSink();
-    switch (node->getOp())
-    {
-        case EOpSequence: {
-            // Scope the sequences except when at the global scope.
-            if (depth > 0) out << "{\n";
-
-            incrementDepth();
-            const TIntermSequence& sequence = node->getSequence();
-            for (TIntermSequence::const_iterator iter = sequence.begin();
-                 iter != sequence.end(); ++iter)
-            {
-                TIntermNode* node = *iter;
-                ASSERT(node != NULL);
-                node->traverse(this);
-
-                if (isSingleStatement(node))
-                    out << ";\n";
-            }
-            decrementDepth();
-
-            // Scope the sequences except when at the global scope.
-            if (depth > 0) out << "}\n";
-            visitChildren = false;
-            break;
-        }
-        case EOpPrototype: {
-            // Function declaration.
-            ASSERT(visit == PreVisit);
-            TString returnType = getTypeName(node->getType());
-            out << returnType << " " << node->getName();
-
-            out << "(";
-            writeFunctionParameters(node->getSequence());
-            out << ")";
-
-            visitChildren = false;
-            break;
-        }
-        case EOpFunction: {
-            // Function definition.
-            ASSERT(visit == PreVisit);
-            TString returnType = getTypeName(node->getType());
-            TString functionName = TFunction::unmangleName(node->getName());
-            out << returnType << " " << functionName;
-
-            incrementDepth();
-            // Function definition node contains one or two children nodes
-            // representing function parameters and function body. The latter
-            // is not present in case of empty function bodies.
-            const TIntermSequence& sequence = node->getSequence();
-            ASSERT((sequence.size() == 1) || (sequence.size() == 2));
-            TIntermSequence::const_iterator seqIter = sequence.begin();
-
-            // Traverse function parameters.
-            TIntermAggregate* params = (*seqIter)->getAsAggregate();
-            ASSERT(params != NULL);
-            ASSERT(params->getOp() == EOpParameters);
-            params->traverse(this);
-
-            // Traverse function body.
-            TIntermAggregate* body = ++seqIter != sequence.end() ?
-                (*seqIter)->getAsAggregate() : NULL;
-            visitCodeBlock(body);
-            decrementDepth();
- 
-            // Fully processed; no need to visit children.
-            visitChildren = false;
-            break;
-        }
-        case EOpFunctionCall:
-            // Function call.
-            if (visit == PreVisit)
-            {
-                TString functionName = TFunction::unmangleName(node->getName());
-                out << functionName << "(";
-            }
-            else if (visit == InVisit)
-            {
-                out << ", ";
-            }
-            else
-            {
-                out << ")";
-            }
-            break;
-        case EOpParameters: {
-            // Function parameters.
-            ASSERT(visit == PreVisit);
-            out << "(";
-            writeFunctionParameters(node->getSequence());
-            out << ")";
-            visitChildren = false;
-            break;
-        }
-        case EOpDeclaration: {
-            // Variable declaration.
-            if (visit == PreVisit)
-            {
-                const TIntermSequence& sequence = node->getSequence();
-                const TIntermTyped* variable = sequence.front()->getAsTyped();
-                writeVariableType(variable->getType());
-                out << " ";
-                mDeclaringVariables = true;
-            }
-            else if (visit == InVisit)
-            {
-                out << ", ";
-                mDeclaringVariables = true;
-            }
-            else
-            {
-                mDeclaringVariables = false;
-            }
-            break;
-        }
-        case EOpConstructFloat: writeTriplet(visit, "float(", NULL, ")"); break;
-        case EOpConstructVec2: writeTriplet(visit, "vec2(", ", ", ")"); break;
-        case EOpConstructVec3: writeTriplet(visit, "vec3(", ", ", ")"); break;
-        case EOpConstructVec4: writeTriplet(visit, "vec4(", ", ", ")"); break;
-        case EOpConstructBool: writeTriplet(visit, "bool(", NULL, ")"); break;
-        case EOpConstructBVec2: writeTriplet(visit, "bvec2(", ", ", ")"); break;
-        case EOpConstructBVec3: writeTriplet(visit, "bvec3(", ", ", ")"); break;
-        case EOpConstructBVec4: writeTriplet(visit, "bvec4(", ", ", ")"); break;
-        case EOpConstructInt: writeTriplet(visit, "int(", NULL, ")"); break;
-        case EOpConstructIVec2: writeTriplet(visit, "ivec2(", ", ", ")"); break;
-        case EOpConstructIVec3: writeTriplet(visit, "ivec3(", ", ", ")"); break;
-        case EOpConstructIVec4: writeTriplet(visit, "ivec4(", ", ", ")"); break;
-        case EOpConstructMat2: writeTriplet(visit, "mat2(", ", ", ")"); break;
-        case EOpConstructMat3: writeTriplet(visit, "mat3(", ", ", ")"); break;
-        case EOpConstructMat4: writeTriplet(visit, "mat4(", ", ", ")"); break;
-        case EOpConstructStruct:
-            if (visit == PreVisit)
-            {
-                const TType& type = node->getType();
-                ASSERT(type.getBasicType() == EbtStruct);
-                out << type.getTypeName() << "(";
-            }
-            else if (visit == InVisit)
-            {
-                out << ", ";
-            }
-            else
-            {
-                out << ")";
-            }
-            break;
-
-        case EOpLessThan: writeTriplet(visit, "lessThan(", ", ", ")"); break;
-        case EOpGreaterThan: writeTriplet(visit, "greaterThan(", ", ", ")"); break;
-        case EOpLessThanEqual: writeTriplet(visit, "lessThanEqual(", ", ", ")"); break;
-        case EOpGreaterThanEqual: writeTriplet(visit, "greaterThanEqual(", ", ", ")"); break;
-        case EOpVectorEqual: writeTriplet(visit, "equal(", ", ", ")"); break;
-        case EOpVectorNotEqual: writeTriplet(visit, "notEqual(", ", ", ")"); break;
-        case EOpComma: writeTriplet(visit, NULL, ", ", NULL); break;
-
-        case EOpMod: writeTriplet(visit, "mod(", ", ", ")"); break;
-        case EOpPow: writeTriplet(visit, "pow(", ", ", ")"); break;
-        case EOpAtan: writeTriplet(visit, "atan(", ", ", ")"); break;
-        case EOpMin: writeTriplet(visit, "min(", ", ", ")"); break;
-        case EOpMax: writeTriplet(visit, "max(", ", ", ")"); break;
-        case EOpClamp: writeTriplet(visit, "clamp(", ", ", ")"); break;
-        case EOpMix: writeTriplet(visit, "mix(", ", ", ")"); break;
-        case EOpStep: writeTriplet(visit, "step(", ", ", ")"); break;
-        case EOpSmoothStep: writeTriplet(visit, "smoothstep(", ", ", ")"); break;
-
-        case EOpDistance: writeTriplet(visit, "distance(", ", ", ")"); break;
-        case EOpDot: writeTriplet(visit, "dot(", ", ", ")"); break;
-        case EOpCross: writeTriplet(visit, "cross(", ", ", ")"); break;
-        case EOpFaceForward: writeTriplet(visit, "faceforward(", ", ", ")"); break;
-        case EOpReflect: writeTriplet(visit, "reflect(", ", ", ")"); break;
-        case EOpRefract: writeTriplet(visit, "refract(", ", ", ")"); break;
-        case EOpMul: writeTriplet(visit, "matrixCompMult(", ", ", ")"); break;
-
-        default: UNREACHABLE(); break;
-    }
-    return visitChildren;
-}
-
-bool TOutputGLSL::visitLoop(Visit visit, TIntermLoop* node)
-{
-    TInfoSinkBase& out = objSink();
-
-    incrementDepth();
-    // Loop header.
-    TLoopType loopType = node->getType();
-    if (loopType == ELoopFor)  // for loop
-    {
-        if (!node->getUnrollFlag()) {
-            out << "for (";
-            if (node->getInit())
-                node->getInit()->traverse(this);
-            out << "; ";
-
-            if (node->getCondition())
-                node->getCondition()->traverse(this);
-            out << "; ";
-
-            if (node->getExpression())
-                node->getExpression()->traverse(this);
-            out << ")\n";
-        }
-    }
-    else if (loopType == ELoopWhile)  // while loop
-    {
-        out << "while (";
-        ASSERT(node->getCondition() != NULL);
-        node->getCondition()->traverse(this);
-        out << ")\n";
-    }
-    else  // do-while loop
-    {
-        ASSERT(loopType == ELoopDoWhile);
-        out << "do\n";
-    }
-
-    // Loop body.
-    if (node->getUnrollFlag())
-    {
-        TLoopIndexInfo indexInfo;
-        mLoopUnroll.FillLoopIndexInfo(node, indexInfo);
-        mLoopUnroll.Push(indexInfo);
-        while (mLoopUnroll.SatisfiesLoopCondition())
-        {
-            visitCodeBlock(node->getBody());
-            mLoopUnroll.Step();
-        }
-        mLoopUnroll.Pop();
-    }
-    else
-    {
-        visitCodeBlock(node->getBody());
-    }
-
-    // Loop footer.
-    if (loopType == ELoopDoWhile)  // do-while loop
-    {
-        out << "while (";
-        ASSERT(node->getCondition() != NULL);
-        node->getCondition()->traverse(this);
-        out << ");\n";
-    }
-    decrementDepth();
-
-    // No need to visit children. They have been already processed in
-    // this function.
-    return false;
-}
-
-bool TOutputGLSL::visitBranch(Visit visit, TIntermBranch* node)
-{
-    switch (node->getFlowOp())
-    {
-        case EOpKill: writeTriplet(visit, "discard", NULL, NULL); break;
-        case EOpBreak: writeTriplet(visit, "break", NULL, NULL); break;
-        case EOpContinue: writeTriplet(visit, "continue", NULL, NULL); break;
-        case EOpReturn: writeTriplet(visit, "return ", NULL, NULL); break;
-        default: UNREACHABLE(); break;
-    }
-
-    return true;
-}
-
-void TOutputGLSL::visitCodeBlock(TIntermNode* node) {
-    TInfoSinkBase &out = objSink();
-    if (node != NULL)
-    {
-        node->traverse(this);
-        // Single statements not part of a sequence need to be terminated
-        // with semi-colon.
-        if (isSingleStatement(node))
-            out << ";\n";
-    }
-    else
-    {
-        out << "{\n}\n";  // Empty code block.
-    }
-}
--- a/gfx/angle/src/compiler/OutputGLSL.h
+++ b/gfx/angle/src/compiler/OutputGLSL.h
@@ -1,52 +1,21 @@
 //
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 #ifndef CROSSCOMPILERGLSL_OUTPUTGLSL_H_
 #define CROSSCOMPILERGLSL_OUTPUTGLSL_H_
 
-#include <set>
+#include "compiler/OutputGLSLBase.h"
 
-#include "compiler/ForLoopUnroll.h"
-#include "compiler/intermediate.h"
-#include "compiler/ParseHelper.h"
-
-class TOutputGLSL : public TIntermTraverser
+class TOutputGLSL : public TOutputGLSLBase
 {
 public:
     TOutputGLSL(TInfoSinkBase& objSink);
 
 protected:
-    TInfoSinkBase& objSink() { return mObjSink; }
-    void writeTriplet(Visit visit, const char* preStr, const char* inStr, const char* postStr);
-    void writeVariableType(const TType& type);
-    void writeFunctionParameters(const TIntermSequence& args);
-    const ConstantUnion* writeConstantUnion(const TType& type, const ConstantUnion* pConstUnion);
-
-    virtual void visitSymbol(TIntermSymbol* node);
-    virtual void visitConstantUnion(TIntermConstantUnion* node);
-    virtual bool visitBinary(Visit visit, TIntermBinary* node);
-    virtual bool visitUnary(Visit visit, TIntermUnary* node);
-    virtual bool visitSelection(Visit visit, TIntermSelection* node);
-    virtual bool visitAggregate(Visit visit, TIntermAggregate* node);
-    virtual bool visitLoop(Visit visit, TIntermLoop* node);
-    virtual bool visitBranch(Visit visit, TIntermBranch* node);
-
-    void visitCodeBlock(TIntermNode* node);
-
-private:
-    TInfoSinkBase& mObjSink;
-    bool mDeclaringVariables;
-
-    // Structs are declared as the tree is traversed. This set contains all
-    // the structs already declared. It is maintained so that a struct is
-    // declared only once.
-    typedef std::set<TString> DeclaredStructs;
-    DeclaredStructs mDeclaredStructs;
-
-    ForLoopUnroll mLoopUnroll;
+    virtual bool writeVariablePrecision(TPrecision);
 };
 
 #endif  // CROSSCOMPILERGLSL_OUTPUTGLSL_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/OutputGLSLBase.cpp
@@ -0,0 +1,714 @@
+//
+// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/OutputGLSLBase.h"
+#include "compiler/compilerdebug.h"
+
+namespace
+{
+TString getTypeName(const TType& type)
+{
+    TInfoSinkBase out;
+    if (type.isMatrix())
+    {
+        out << "mat";
+        out << type.getNominalSize();
+    }
+    else if (type.isVector())
+    {
+        switch (type.getBasicType())
+        {
+            case EbtFloat: out << "vec"; break;
+            case EbtInt: out << "ivec"; break;
+            case EbtBool: out << "bvec"; break;
+            default: UNREACHABLE(); break;
+        }
+        out << type.getNominalSize();
+    }
+    else
+    {
+        if (type.getBasicType() == EbtStruct)
+            out << type.getTypeName();
+        else
+            out << type.getBasicString();
+    }
+    return TString(out.c_str());
+}
+
+TString arrayBrackets(const TType& type)
+{
+    ASSERT(type.isArray());
+    TInfoSinkBase out;
+    out << "[" << type.getArraySize() << "]";
+    return TString(out.c_str());
+}
+
+bool isSingleStatement(TIntermNode* node) {
+    if (const TIntermAggregate* aggregate = node->getAsAggregate())
+    {
+        return (aggregate->getOp() != EOpFunction) &&
+               (aggregate->getOp() != EOpSequence);
+    }
+    else if (const TIntermSelection* selection = node->getAsSelectionNode())
+    {
+        // Ternary operators are usually part of an assignment operator.
+        // This handles those rare cases in which they are all by themselves.
+        return selection->usesTernaryOperator();
+    }
+    else if (node->getAsLoopNode())
+    {
+        return false;
+    }
+    return true;
+}
+}  // namespace
+
+TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase& objSink)
+    : TIntermTraverser(true, true, true),
+      mObjSink(objSink),
+      mDeclaringVariables(false)
+{
+}
+
+void TOutputGLSLBase::writeTriplet(Visit visit, const char* preStr, const char* inStr, const char* postStr)
+{
+    TInfoSinkBase& out = objSink();
+    if (visit == PreVisit && preStr)
+    {
+        out << preStr;
+    }
+    else if (visit == InVisit && inStr)
+    {
+        out << inStr;
+    }
+    else if (visit == PostVisit && postStr)
+    {
+        out << postStr;
+    }
+}
+
+void TOutputGLSLBase::writeVariableType(const TType& type)
+{
+    TInfoSinkBase& out = objSink();
+    TQualifier qualifier = type.getQualifier();
+    // TODO(alokp): Validate qualifier for variable declarations.
+    if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal))
+        out << type.getQualifierString() << " ";
+    // Declare the struct if we have not done so already.
+    if ((type.getBasicType() == EbtStruct) &&
+        (mDeclaredStructs.find(type.getTypeName()) == mDeclaredStructs.end()))
+    {
+        out << "struct " << type.getTypeName() << "{\n";
+        const TTypeList* structure = type.getStruct();
+        ASSERT(structure != NULL);
+        for (size_t i = 0; i < structure->size(); ++i)
+        {
+            const TType* fieldType = (*structure)[i].type;
+            ASSERT(fieldType != NULL);
+            if (writeVariablePrecision(fieldType->getPrecision()))
+                out << " ";
+            out << getTypeName(*fieldType) << " " << fieldType->getFieldName();
+            if (fieldType->isArray())
+                out << arrayBrackets(*fieldType);
+            out << ";\n";
+        }
+        out << "}";
+        mDeclaredStructs.insert(type.getTypeName());
+    }
+    else
+    {
+        if (writeVariablePrecision(type.getPrecision()))
+            out << " ";
+        out << getTypeName(type);
+    }
+}
+
+void TOutputGLSLBase::writeFunctionParameters(const TIntermSequence& args)
+{
+    TInfoSinkBase& out = objSink();
+    for (TIntermSequence::const_iterator iter = args.begin();
+         iter != args.end(); ++iter)
+    {
+        const TIntermSymbol* arg = (*iter)->getAsSymbolNode();
+        ASSERT(arg != NULL);
+
+        const TType& type = arg->getType();
+        writeVariableType(type);
+
+        const TString& name = arg->getSymbol();
+        if (!name.empty())
+            out << " " << name;
+        if (type.isArray())
+            out << arrayBrackets(type);
+
+        // Put a comma if this is not the last argument.
+        if (iter != args.end() - 1)
+            out << ", ";
+    }
+}
+
+const ConstantUnion* TOutputGLSLBase::writeConstantUnion(const TType& type,
+                                                         const ConstantUnion* pConstUnion)
+{
+    TInfoSinkBase& out = objSink();
+
+    if (type.getBasicType() == EbtStruct)
+    {
+        out << type.getTypeName() << "(";
+        const TTypeList* structure = type.getStruct();
+        ASSERT(structure != NULL);
+        for (size_t i = 0; i < structure->size(); ++i)
+        {
+            const TType* fieldType = (*structure)[i].type;
+            ASSERT(fieldType != NULL);
+            pConstUnion = writeConstantUnion(*fieldType, pConstUnion);
+            if (i != structure->size() - 1) out << ", ";
+        }
+        out << ")";
+    }
+    else
+    {
+        int size = type.getObjectSize();
+        bool writeType = size > 1;
+        if (writeType) out << getTypeName(type) << "(";
+        for (int i = 0; i < size; ++i, ++pConstUnion)
+        {
+            switch (pConstUnion->getType())
+            {
+                case EbtFloat: out << pConstUnion->getFConst(); break;
+                case EbtInt: out << pConstUnion->getIConst(); break;
+                case EbtBool: out << pConstUnion->getBConst(); break;
+                default: UNREACHABLE();
+            }
+            if (i != size - 1) out << ", ";
+        }
+        if (writeType) out << ")";
+    }
+    return pConstUnion;
+}
+
+void TOutputGLSLBase::visitSymbol(TIntermSymbol* node)
+{
+    TInfoSinkBase& out = objSink();
+    if (mLoopUnroll.NeedsToReplaceSymbolWithValue(node))
+        out << mLoopUnroll.GetLoopIndexValue(node);
+    else
+        out << node->getSymbol();
+
+    if (mDeclaringVariables && node->getType().isArray())
+        out << arrayBrackets(node->getType());
+}
+
+void TOutputGLSLBase::visitConstantUnion(TIntermConstantUnion* node)
+{
+    writeConstantUnion(node->getType(), node->getUnionArrayPointer());
+}
+
+bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary* node)
+{
+    bool visitChildren = true;
+    TInfoSinkBase& out = objSink();
+    switch (node->getOp())
+    {
+        case EOpInitialize:
+            if (visit == InVisit)
+            {
+                out << " = ";
+                // RHS of initialize is not being declared.
+                mDeclaringVariables = false;
+            }
+            break;
+        case EOpAssign: writeTriplet(visit, "(", " = ", ")"); break;
+        case EOpAddAssign: writeTriplet(visit, "(", " += ", ")"); break;
+        case EOpSubAssign: writeTriplet(visit, "(", " -= ", ")"); break;
+        case EOpDivAssign: writeTriplet(visit, "(", " /= ", ")"); break;
+        // Notice the fall-through.
+        case EOpMulAssign: 
+        case EOpVectorTimesMatrixAssign:
+        case EOpVectorTimesScalarAssign:
+        case EOpMatrixTimesScalarAssign:
+        case EOpMatrixTimesMatrixAssign:
+            writeTriplet(visit, "(", " *= ", ")");
+            break;
+
+        case EOpIndexDirect:
+        case EOpIndexIndirect:
+            writeTriplet(visit, NULL, "[", "]");
+            break;
+        case EOpIndexDirectStruct:
+            if (visit == InVisit)
+            {
+                out << ".";
+                // TODO(alokp): ASSERT
+                out << node->getType().getFieldName();
+                visitChildren = false;
+            }
+            break;
+        case EOpVectorSwizzle:
+            if (visit == InVisit)
+            {
+                out << ".";
+                TIntermAggregate* rightChild = node->getRight()->getAsAggregate();
+                TIntermSequence& sequence = rightChild->getSequence();
+                for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); ++sit)
+                {
+                    TIntermConstantUnion* element = (*sit)->getAsConstantUnion();
+                    ASSERT(element->getBasicType() == EbtInt);
+                    ASSERT(element->getNominalSize() == 1);
+                    const ConstantUnion& data = element->getUnionArrayPointer()[0];
+                    ASSERT(data.getType() == EbtInt);
+                    switch (data.getIConst())
+                    {
+                        case 0: out << "x"; break;
+                        case 1: out << "y"; break;
+                        case 2: out << "z"; break;
+                        case 3: out << "w"; break;
+                        default: UNREACHABLE(); break;
+                    }
+                }
+                visitChildren = false;
+            }
+            break;
+
+        case EOpAdd: writeTriplet(visit, "(", " + ", ")"); break;
+        case EOpSub: writeTriplet(visit, "(", " - ", ")"); break;
+        case EOpMul: writeTriplet(visit, "(", " * ", ")"); break;
+        case EOpDiv: writeTriplet(visit, "(", " / ", ")"); break;
+        case EOpMod: UNIMPLEMENTED(); break;
+        case EOpEqual: writeTriplet(visit, "(", " == ", ")"); break;
+        case EOpNotEqual: writeTriplet(visit, "(", " != ", ")"); break;
+        case EOpLessThan: writeTriplet(visit, "(", " < ", ")"); break;
+        case EOpGreaterThan: writeTriplet(visit, "(", " > ", ")"); break;
+        case EOpLessThanEqual: writeTriplet(visit, "(", " <= ", ")"); break;
+        case EOpGreaterThanEqual: writeTriplet(visit, "(", " >= ", ")"); break;
+
+        // Notice the fall-through.
+        case EOpVectorTimesScalar:
+        case EOpVectorTimesMatrix:
+        case EOpMatrixTimesVector:
+        case EOpMatrixTimesScalar:
+        case EOpMatrixTimesMatrix:
+            writeTriplet(visit, "(", " * ", ")");
+            break;
+
+        case EOpLogicalOr: writeTriplet(visit, "(", " || ", ")"); break;
+        case EOpLogicalXor: writeTriplet(visit, "(", " ^^ ", ")"); break;
+        case EOpLogicalAnd: writeTriplet(visit, "(", " && ", ")"); break;
+        default: UNREACHABLE(); break;
+    }
+
+    return visitChildren;
+}
+
+bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary* node)
+{
+    TString preString;
+    TString postString = ")";
+
+    switch (node->getOp())
+    {
+        case EOpNegative: preString = "(-"; break;
+        case EOpVectorLogicalNot: preString = "not("; break;
+        case EOpLogicalNot: preString = "(!"; break;
+
+        case EOpPostIncrement: preString = "("; postString = "++)"; break;
+        case EOpPostDecrement: preString = "("; postString = "--)"; break;
+        case EOpPreIncrement: preString = "(++"; break;
+        case EOpPreDecrement: preString = "(--"; break;
+
+        case EOpConvIntToBool:
+        case EOpConvFloatToBool:
+            switch (node->getOperand()->getType().getNominalSize())
+            {
+                case 1: preString =  "bool(";  break;
+                case 2: preString = "bvec2("; break;
+                case 3: preString = "bvec3("; break;
+                case 4: preString = "bvec4("; break;
+                default: UNREACHABLE();
+            }
+            break;
+        case EOpConvBoolToFloat:
+        case EOpConvIntToFloat:
+            switch (node->getOperand()->getType().getNominalSize())
+            {
+                case 1: preString = "float(";  break;
+                case 2: preString = "vec2("; break;
+                case 3: preString = "vec3("; break;
+                case 4: preString = "vec4("; break;
+                default: UNREACHABLE();
+            }
+            break;
+        case EOpConvFloatToInt:
+        case EOpConvBoolToInt:
+            switch (node->getOperand()->getType().getNominalSize())
+            {
+                case 1: preString = "int(";  break;
+                case 2: preString = "ivec2("; break;
+                case 3: preString = "ivec3("; break;
+                case 4: preString = "ivec4("; break;
+                default: UNREACHABLE();
+            }
+            break;
+
+        case EOpRadians: preString = "radians("; break;
+        case EOpDegrees: preString = "degrees("; break;
+        case EOpSin: preString = "sin("; break;
+        case EOpCos: preString = "cos("; break;
+        case EOpTan: preString = "tan("; break;
+        case EOpAsin: preString = "asin("; break;
+        case EOpAcos: preString = "acos("; break;
+        case EOpAtan: preString = "atan("; break;
+
+        case EOpExp: preString = "exp("; break;
+        case EOpLog: preString = "log("; break;
+        case EOpExp2: preString = "exp2("; break;
+        case EOpLog2: preString = "log2("; break;
+        case EOpSqrt: preString = "sqrt("; break;
+        case EOpInverseSqrt: preString = "inversesqrt("; break;
+
+        case EOpAbs: preString = "abs("; break;
+        case EOpSign: preString = "sign("; break;
+        case EOpFloor: preString = "floor("; break;
+        case EOpCeil: preString = "ceil("; break;
+        case EOpFract: preString = "fract("; break;
+
+        case EOpLength: preString = "length("; break;
+        case EOpNormalize: preString = "normalize("; break;
+
+        case EOpDFdx: preString = "dFdx("; break;
+        case EOpDFdy: preString = "dFdy("; break;
+        case EOpFwidth: preString = "fwidth("; break;
+
+        case EOpAny: preString = "any("; break;
+        case EOpAll: preString = "all("; break;
+
+        default: UNREACHABLE(); break;
+    }
+
+    if (visit == PreVisit && node->getUseEmulatedFunction())
+        preString = BuiltInFunctionEmulator::GetEmulatedFunctionName(preString);
+    writeTriplet(visit, preString.c_str(), NULL, postString.c_str());
+
+    return true;
+}
+
+bool TOutputGLSLBase::visitSelection(Visit visit, TIntermSelection* node)
+{
+    TInfoSinkBase& out = objSink();
+
+    if (node->usesTernaryOperator())
+    {
+        // Notice two brackets at the beginning and end. The outer ones
+        // encapsulate the whole ternary expression. This preserves the
+        // order of precedence when ternary expressions are used in a
+        // compound expression, i.e., c = 2 * (a < b ? 1 : 2).
+        out << "((";
+        node->getCondition()->traverse(this);
+        out << ") ? (";
+        node->getTrueBlock()->traverse(this);
+        out << ") : (";
+        node->getFalseBlock()->traverse(this);
+        out << "))";
+    }
+    else
+    {
+        out << "if (";
+        node->getCondition()->traverse(this);
+        out << ")\n";
+
+        incrementDepth();
+        visitCodeBlock(node->getTrueBlock());
+
+        if (node->getFalseBlock())
+        {
+            out << "else\n";
+            visitCodeBlock(node->getFalseBlock());
+        }
+        decrementDepth();
+    }
+    return false;
+}
+
+bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate* node)
+{
+    bool visitChildren = true;
+    TInfoSinkBase& out = objSink();
+    switch (node->getOp())
+    {
+        case EOpSequence: {
+            // Scope the sequences except when at the global scope.
+            if (depth > 0) out << "{\n";
+
+            incrementDepth();
+            const TIntermSequence& sequence = node->getSequence();
+            for (TIntermSequence::const_iterator iter = sequence.begin();
+                 iter != sequence.end(); ++iter)
+            {
+                TIntermNode* node = *iter;
+                ASSERT(node != NULL);
+                node->traverse(this);
+
+                if (isSingleStatement(node))
+                    out << ";\n";
+            }
+            decrementDepth();
+
+            // Scope the sequences except when at the global scope.
+            if (depth > 0) out << "}\n";
+            visitChildren = false;
+            break;
+        }
+        case EOpPrototype: {
+            // Function declaration.
+            ASSERT(visit == PreVisit);
+            writeVariableType(node->getType());
+            out << " " << node->getName();
+
+            out << "(";
+            writeFunctionParameters(node->getSequence());
+            out << ")";
+
+            visitChildren = false;
+            break;
+        }
+        case EOpFunction: {
+            // Function definition.
+            ASSERT(visit == PreVisit);
+            writeVariableType(node->getType());
+            out << " " << TFunction::unmangleName(node->getName());
+
+            incrementDepth();
+            // Function definition node contains one or two children nodes
+            // representing function parameters and function body. The latter
+            // is not present in case of empty function bodies.
+            const TIntermSequence& sequence = node->getSequence();
+            ASSERT((sequence.size() == 1) || (sequence.size() == 2));
+            TIntermSequence::const_iterator seqIter = sequence.begin();
+
+            // Traverse function parameters.
+            TIntermAggregate* params = (*seqIter)->getAsAggregate();
+            ASSERT(params != NULL);
+            ASSERT(params->getOp() == EOpParameters);
+            params->traverse(this);
+
+            // Traverse function body.
+            TIntermAggregate* body = ++seqIter != sequence.end() ?
+                (*seqIter)->getAsAggregate() : NULL;
+            visitCodeBlock(body);
+            decrementDepth();
+ 
+            // Fully processed; no need to visit children.
+            visitChildren = false;
+            break;
+        }
+        case EOpFunctionCall:
+            // Function call.
+            if (visit == PreVisit)
+            {
+                TString functionName = TFunction::unmangleName(node->getName());
+                out << functionName << "(";
+            }
+            else if (visit == InVisit)
+            {
+                out << ", ";
+            }
+            else
+            {
+                out << ")";
+            }
+            break;
+        case EOpParameters: {
+            // Function parameters.
+            ASSERT(visit == PreVisit);
+            out << "(";
+            writeFunctionParameters(node->getSequence());
+            out << ")";
+            visitChildren = false;
+            break;
+        }
+        case EOpDeclaration: {
+            // Variable declaration.
+            if (visit == PreVisit)
+            {
+                const TIntermSequence& sequence = node->getSequence();
+                const TIntermTyped* variable = sequence.front()->getAsTyped();
+                writeVariableType(variable->getType());
+                out << " ";
+                mDeclaringVariables = true;
+            }
+            else if (visit == InVisit)
+            {
+                out << ", ";
+                mDeclaringVariables = true;
+            }
+            else
+            {
+                mDeclaringVariables = false;
+            }
+            break;
+        }
+        case EOpConstructFloat: writeTriplet(visit, "float(", NULL, ")"); break;
+        case EOpConstructVec2: writeTriplet(visit, "vec2(", ", ", ")"); break;
+        case EOpConstructVec3: writeTriplet(visit, "vec3(", ", ", ")"); break;
+        case EOpConstructVec4: writeTriplet(visit, "vec4(", ", ", ")"); break;
+        case EOpConstructBool: writeTriplet(visit, "bool(", NULL, ")"); break;
+        case EOpConstructBVec2: writeTriplet(visit, "bvec2(", ", ", ")"); break;
+        case EOpConstructBVec3: writeTriplet(visit, "bvec3(", ", ", ")"); break;
+        case EOpConstructBVec4: writeTriplet(visit, "bvec4(", ", ", ")"); break;
+        case EOpConstructInt: writeTriplet(visit, "int(", NULL, ")"); break;
+        case EOpConstructIVec2: writeTriplet(visit, "ivec2(", ", ", ")"); break;
+        case EOpConstructIVec3: writeTriplet(visit, "ivec3(", ", ", ")"); break;
+        case EOpConstructIVec4: writeTriplet(visit, "ivec4(", ", ", ")"); break;
+        case EOpConstructMat2: writeTriplet(visit, "mat2(", ", ", ")"); break;
+        case EOpConstructMat3: writeTriplet(visit, "mat3(", ", ", ")"); break;
+        case EOpConstructMat4: writeTriplet(visit, "mat4(", ", ", ")"); break;
+        case EOpConstructStruct:
+            if (visit == PreVisit)
+            {
+                const TType& type = node->getType();
+                ASSERT(type.getBasicType() == EbtStruct);
+                out << type.getTypeName() << "(";
+            }
+            else if (visit == InVisit)
+            {
+                out << ", ";
+            }
+            else
+            {
+                out << ")";
+            }
+            break;
+
+        case EOpLessThan: writeTriplet(visit, "lessThan(", ", ", ")"); break;
+        case EOpGreaterThan: writeTriplet(visit, "greaterThan(", ", ", ")"); break;
+        case EOpLessThanEqual: writeTriplet(visit, "lessThanEqual(", ", ", ")"); break;
+        case EOpGreaterThanEqual: writeTriplet(visit, "greaterThanEqual(", ", ", ")"); break;
+        case EOpVectorEqual: writeTriplet(visit, "equal(", ", ", ")"); break;
+        case EOpVectorNotEqual: writeTriplet(visit, "notEqual(", ", ", ")"); break;
+        case EOpComma: writeTriplet(visit, NULL, ", ", NULL); break;
+
+        case EOpMod: writeTriplet(visit, "mod(", ", ", ")"); break;
+        case EOpPow: writeTriplet(visit, "pow(", ", ", ")"); break;
+        case EOpAtan: writeTriplet(visit, "atan(", ", ", ")"); break;
+        case EOpMin: writeTriplet(visit, "min(", ", ", ")"); break;
+        case EOpMax: writeTriplet(visit, "max(", ", ", ")"); break;
+        case EOpClamp: writeTriplet(visit, "clamp(", ", ", ")"); break;
+        case EOpMix: writeTriplet(visit, "mix(", ", ", ")"); break;
+        case EOpStep: writeTriplet(visit, "step(", ", ", ")"); break;
+        case EOpSmoothStep: writeTriplet(visit, "smoothstep(", ", ", ")"); break;
+
+        case EOpDistance: writeTriplet(visit, "distance(", ", ", ")"); break;
+        case EOpDot: writeTriplet(visit, "dot(", ", ", ")"); break;
+        case EOpCross: writeTriplet(visit, "cross(", ", ", ")"); break;
+        case EOpFaceForward: writeTriplet(visit, "faceforward(", ", ", ")"); break;
+        case EOpReflect: writeTriplet(visit, "reflect(", ", ", ")"); break;
+        case EOpRefract: writeTriplet(visit, "refract(", ", ", ")"); break;
+        case EOpMul: writeTriplet(visit, "matrixCompMult(", ", ", ")"); break;
+
+        default: UNREACHABLE(); break;
+    }
+    return visitChildren;
+}
+
+bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop* node)
+{
+    TInfoSinkBase& out = objSink();
+
+    incrementDepth();
+    // Loop header.
+    TLoopType loopType = node->getType();
+    if (loopType == ELoopFor)  // for loop
+    {
+        if (!node->getUnrollFlag()) {
+            out << "for (";
+            if (node->getInit())
+                node->getInit()->traverse(this);
+            out << "; ";
+
+            if (node->getCondition())
+                node->getCondition()->traverse(this);
+            out << "; ";
+
+            if (node->getExpression())
+                node->getExpression()->traverse(this);
+            out << ")\n";
+        }
+    }
+    else if (loopType == ELoopWhile)  // while loop
+    {
+        out << "while (";
+        ASSERT(node->getCondition() != NULL);
+        node->getCondition()->traverse(this);
+        out << ")\n";
+    }
+    else  // do-while loop
+    {
+        ASSERT(loopType == ELoopDoWhile);
+        out << "do\n";
+    }
+
+    // Loop body.
+    if (node->getUnrollFlag())
+    {
+        TLoopIndexInfo indexInfo;
+        mLoopUnroll.FillLoopIndexInfo(node, indexInfo);
+        mLoopUnroll.Push(indexInfo);
+        while (mLoopUnroll.SatisfiesLoopCondition())
+        {
+            visitCodeBlock(node->getBody());
+            mLoopUnroll.Step();
+        }
+        mLoopUnroll.Pop();
+    }
+    else
+    {
+        visitCodeBlock(node->getBody());
+    }
+
+    // Loop footer.
+    if (loopType == ELoopDoWhile)  // do-while loop
+    {
+        out << "while (";
+        ASSERT(node->getCondition() != NULL);
+        node->getCondition()->traverse(this);
+        out << ");\n";
+    }
+    decrementDepth();
+
+    // No need to visit children. They have been already processed in
+    // this function.
+    return false;
+}
+
+bool TOutputGLSLBase::visitBranch(Visit visit, TIntermBranch* node)
+{
+    switch (node->getFlowOp())
+    {
+        case EOpKill: writeTriplet(visit, "discard", NULL, NULL); break;
+        case EOpBreak: writeTriplet(visit, "break", NULL, NULL); break;
+        case EOpContinue: writeTriplet(visit, "continue", NULL, NULL); break;
+        case EOpReturn: writeTriplet(visit, "return ", NULL, NULL); break;
+        default: UNREACHABLE(); break;
+    }
+
+    return true;
+}
+
+void TOutputGLSLBase::visitCodeBlock(TIntermNode* node) {
+    TInfoSinkBase &out = objSink();
+    if (node != NULL)
+    {
+        node->traverse(this);
+        // Single statements not part of a sequence need to be terminated
+        // with semi-colon.
+        if (isSingleStatement(node))
+            out << ";\n";
+    }
+    else
+    {
+        out << "{\n}\n";  // Empty code block.
+    }
+}
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/OutputGLSLBase.h
@@ -0,0 +1,53 @@
+//
+// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef CROSSCOMPILERGLSL_OUTPUTGLSLBASE_H_
+#define CROSSCOMPILERGLSL_OUTPUTGLSLBASE_H_
+
+#include <set>
+
+#include "compiler/ForLoopUnroll.h"
+#include "compiler/intermediate.h"
+#include "compiler/ParseHelper.h"
+
+class TOutputGLSLBase : public TIntermTraverser
+{
+public:
+    TOutputGLSLBase(TInfoSinkBase& objSink);
+
+protected:
+    TInfoSinkBase& objSink() { return mObjSink; }
+    void writeTriplet(Visit visit, const char* preStr, const char* inStr, const char* postStr);
+    void writeVariableType(const TType& type);
+    virtual bool writeVariablePrecision(TPrecision precision) = 0;
+    void writeFunctionParameters(const TIntermSequence& args);
+    const ConstantUnion* writeConstantUnion(const TType& type, const ConstantUnion* pConstUnion);
+
+    virtual void visitSymbol(TIntermSymbol* node);
+    virtual void visitConstantUnion(TIntermConstantUnion* node);
+    virtual bool visitBinary(Visit visit, TIntermBinary* node);
+    virtual bool visitUnary(Visit visit, TIntermUnary* node);
+    virtual bool visitSelection(Visit visit, TIntermSelection* node);
+    virtual bool visitAggregate(Visit visit, TIntermAggregate* node);
+    virtual bool visitLoop(Visit visit, TIntermLoop* node);
+    virtual bool visitBranch(Visit visit, TIntermBranch* node);
+
+    void visitCodeBlock(TIntermNode* node);
+
+private:
+    TInfoSinkBase& mObjSink;
+    bool mDeclaringVariables;
+
+    // Structs are declared as the tree is traversed. This set contains all
+    // the structs already declared. It is maintained so that a struct is
+    // declared only once.
+    typedef std::set<TString> DeclaredStructs;
+    DeclaredStructs mDeclaredStructs;
+
+    ForLoopUnroll mLoopUnroll;
+};
+
+#endif  // CROSSCOMPILERGLSL_OUTPUTGLSLBASE_H_
--- a/gfx/angle/src/compiler/ParseHelper.cpp
+++ b/gfx/angle/src/compiler/ParseHelper.cpp
@@ -191,17 +191,16 @@ bool TParseContext::parseMatrixFields(co
 //
 ////////////////////////////////////////////////////////////////////////
 
 //
 // Track whether errors have occurred.
 //
 void TParseContext::recover()
 {
-    recoveredFromError = true;
 }
 
 //
 // Used by flex/bison to output all syntax and parsing errors.
 //
 void TParseContext::error(TSourceLoc loc,
                           const char* reason, const char* token, 
                           const char* extraInfoFormat, ...)
@@ -256,16 +255,18 @@ void TParseContext::binaryOpError(int li
 {
     error(line, " wrong operand types ", op, 
             "no operation '%s' exists that takes a left-hand operand of type '%s' and "
             "a right operand of type '%s' (or there is no acceptable conversion)", 
             op, left.c_str(), right.c_str());
 }
 
 bool TParseContext::precisionErrorCheck(int line, TPrecision precision, TBasicType type){
+    if (!checksPrecisionErrors)
+        return false;
     switch( type ){
     case EbtFloat:
         if( precision == EbpUndefined ){
             error( line, "No precision specified for (float)", "", "" );
             return true;
         }
         break;
     case EbtInt:
@@ -936,16 +937,22 @@ bool TParseContext::extensionErrorCheck(
         TString msg = "extension " + extension + " is being used";
         infoSink.info.message(EPrefixWarning, msg.c_str(), line);
         return false;
     }
 
     return false;
 }
 
+bool TParseContext::supportsExtension(const char* extension)
+{
+    TExtensionBehavior::const_iterator iter = extensionBehavior.find(extension);
+    return (iter != extensionBehavior.end());
+}
+
 /////////////////////////////////////////////////////////////////////////////////
 //
 // Non-Errors.
 //
 /////////////////////////////////////////////////////////////////////////////////
 
 //
 // Look up a function name in the symbol table, and make sure it is a function.
--- a/gfx/angle/src/compiler/ParseHelper.h
+++ b/gfx/angle/src/compiler/ParseHelper.h
@@ -25,46 +25,51 @@ struct TPragma {
     TPragmaTable pragmaTable;
 };
 
 //
 // The following are extra variables needed during parsing, grouped together so
 // they can be passed to the parser without needing a global.
 //
 struct TParseContext {
-    TParseContext(TSymbolTable& symt, const TExtensionBehavior& ext, TIntermediate& interm, ShShaderType type, ShShaderSpec spec, int options, const char* sourcePath, TInfoSink& is) :
-            intermediate(interm), symbolTable(symt), extensionBehavior(ext), infoSink(is), shaderType(type), shaderSpec(spec), compileOptions(options), sourcePath(sourcePath), treeRoot(0),
-            recoveredFromError(false), numErrors(0), lexAfterType(false), loopNestingLevel(0),
-            inTypeParen(false), scanner(NULL), contextPragma(true, false) {  }
+    TParseContext(TSymbolTable& symt, TExtensionBehavior& ext, TIntermediate& interm, ShShaderType type, ShShaderSpec spec, int options, bool checksPrecErrors, const char* sourcePath, TInfoSink& is) :
+            intermediate(interm), symbolTable(symt), extensionBehavior(ext), infoSink(is), shaderType(type), shaderSpec(spec), compileOptions(options), checksPrecisionErrors(checksPrecErrors), sourcePath(sourcePath), treeRoot(0),
+            numErrors(0), lexAfterType(false), loopNestingLevel(0),
+            inTypeParen(false), contextPragma(true, false), scanner(NULL) {  }
     TIntermediate& intermediate; // to hold and build a parse tree
     TSymbolTable& symbolTable;   // symbol table that goes with the language currently being parsed
-    TExtensionBehavior extensionBehavior;  // mapping between supported extensions and current behavior.
+    TExtensionBehavior& extensionBehavior;  // mapping between supported extensions and current behavior.
     TInfoSink& infoSink;
     ShShaderType shaderType;              // vertex or fragment language (future: pack or unpack)
     ShShaderSpec shaderSpec;              // The language specification compiler conforms to - GLES2 or WebGL.
     int compileOptions;
     const char* sourcePath;      // Path of source file or NULL.
     TIntermNode* treeRoot;       // root of parse tree being created
-    bool recoveredFromError;     // true if a parse error has occurred, but we continue to parse
     int numErrors;
     bool lexAfterType;           // true if we've recognized a type, so can only be looking for an identifier
     int loopNestingLevel;        // 0 if outside all loops
     bool inTypeParen;            // true if in parentheses, looking only for an identifier
     const TType* currentFunctionType;  // the return type of the function that's currently being parsed
     bool functionReturnsValue;   // true if a non-void function has a return
+    bool checksPrecisionErrors;  // true if an error will be generated when a variable is declared without precision, explicit or implicit.
+    struct TPragma contextPragma;
+    TString HashErrMsg;
+    bool AfterEOF;
+    void* scanner;
 
     void error(TSourceLoc loc, const char *reason, const char* token,
                const char* extraInfoFormat, ...);
     void warning(TSourceLoc loc, const char* reason, const char* token,
                  const char* extraInfoFormat, ...);
-    bool reservedErrorCheck(int line, const TString& identifier);
     void recover();
 
     bool parseVectorFields(const TString&, int vecSize, TVectorFields&, int line);
     bool parseMatrixFields(const TString&, int matSize, TMatrixFields&, int line);
+
+    bool reservedErrorCheck(int line, const TString& identifier);
     void assignError(int line, const char* op, TString left, TString right);
     void unaryOpError(int line, const char* op, TString operand);
     void binaryOpError(int line, const char* op, TString left, TString right);
     bool precisionErrorCheck(int line, TPrecision precision, TBasicType type);
     bool lValueErrorCheck(int line, const char* op, TIntermTyped*);
     bool constErrorCheck(TIntermTyped* node);
     bool integerErrorCheck(TIntermTyped* node, const char* token);
     bool globalErrorCheck(int line, bool global, const char* token);
@@ -74,38 +79,37 @@ struct TParseContext {
     bool arrayTypeErrorCheck(int line, TPublicType type);
     bool arrayErrorCheck(int line, TString& identifier, TPublicType type, TVariable*& variable);
     bool voidErrorCheck(int, const TString&, const TPublicType&);
     bool boolErrorCheck(int, const TIntermTyped*);
     bool boolErrorCheck(int, const TPublicType&);
     bool samplerErrorCheck(int line, const TPublicType& pType, const char* reason);
     bool structQualifierErrorCheck(int line, const TPublicType& pType);
     bool parameterSamplerErrorCheck(int line, TQualifier qualifier, const TType& type);
-    bool containsSampler(TType& type);
     bool nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type);
     bool nonInitErrorCheck(int line, TString& identifier, TPublicType& type, TVariable*& variable);
     bool paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type);
     bool extensionErrorCheck(int line, const TString&);
+    bool supportsExtension(const char* extension);
+
+    bool containsSampler(TType& type);
+    bool areAllChildConst(TIntermAggregate* aggrNode);
     const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0);
     bool executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType,
                             TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0);
-    bool areAllChildConst(TIntermAggregate* aggrNode);
+    bool arraySetMaxSize(TIntermSymbol*, TType*, int, bool, TSourceLoc);
+
     TIntermTyped* addConstructor(TIntermNode*, const TType*, TOperator, TFunction*, TSourceLoc);
     TIntermTyped* foldConstConstructor(TIntermAggregate* aggrNode, const TType& type);
     TIntermTyped* constructStruct(TIntermNode*, TType*, int, TSourceLoc, bool subset);
     TIntermTyped* constructBuiltIn(const TType*, TOperator, TIntermNode*, TSourceLoc, bool subset);
     TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, TSourceLoc);
     TIntermTyped* addConstMatrixNode(int , TIntermTyped*, TSourceLoc);
     TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line);
     TIntermTyped* addConstStruct(TString& , TIntermTyped*, TSourceLoc);
-    bool arraySetMaxSize(TIntermSymbol*, TType*, int, bool, TSourceLoc);
-    void* scanner;
-    struct TPragma contextPragma;
-    TString HashErrMsg;
-    bool AfterEOF;
 };
 
 int PaParseStrings(int count, const char* const string[], const int length[],
                    TParseContext* context);
 
 typedef TParseContext* TParseContextPointer;
 extern TParseContextPointer& GetGlobalParseContext();
 #define GlobalParseContext GetGlobalParseContext()
--- a/gfx/angle/src/compiler/ShHandle.h
+++ b/gfx/angle/src/compiler/ShHandle.h
@@ -11,16 +11,17 @@
 // Machine independent part of the compiler private objects
 // sent as ShHandle to the driver.
 //
 // This should not be included by driver code.
 //
 
 #include "GLSLANG/ShaderLang.h"
 
+#include "compiler/BuiltInFunctionEmulator.h"
 #include "compiler/ExtensionBehavior.h"
 #include "compiler/InfoSink.h"
 #include "compiler/SymbolTable.h"
 #include "compiler/VariableInfo.h"
 
 class TCompiler;
 
 //
@@ -72,27 +73,33 @@ protected:
     // functionality mandated in GLSL 1.0 spec Appendix A.
     bool validateLimitations(TIntermNode* root);
     // Collect info for all attribs and uniforms.
     void collectAttribsUniforms(TIntermNode* root);
     // Map long variable names into shorter ones.
     void mapLongVariableNames(TIntermNode* root);
     // Translate to object code.
     virtual void translate(TIntermNode* root) = 0;
+    // Get built-in extensions with default behavior.
+    const TExtensionBehavior& getExtensionBehavior() const;
+
+    const BuiltInFunctionEmulator& getBuiltInFunctionEmulator() const;
 
 private:
     ShShaderType shaderType;
     ShShaderSpec shaderSpec;
 
     // Built-in symbol table for the given language, spec, and resources.
     // It is preserved from compile-to-compile.
     TSymbolTable symbolTable;
     // Built-in extensions with default behavior.
     TExtensionBehavior extensionBehavior;
 
+    BuiltInFunctionEmulator builtInFunctionEmulator;
+
     // Results of compilation.
     TInfoSink infoSink;  // Output sink.
     TVariableInfoList attribs;  // Active attributes in the compiled shader.
     TVariableInfoList uniforms;  // Active uniforms in the compiled shader.
 
     // Pair of long varying varibale name <originalName, mappedName>.
     TMap<TString, TString> varyingLongNameMap;
 };
@@ -101,12 +108,13 @@ private:
 // This is the interface between the machine independent code
 // and the machine dependent code.
 //
 // The machine dependent code should derive from the classes
 // above. Then Construct*() and Delete*() will create and 
 // destroy the machine dependent objects, which contain the
 // above machine independent information.
 //
-TCompiler* ConstructCompiler(ShShaderType type, ShShaderSpec spec);
+TCompiler* ConstructCompiler(
+    ShShaderType type, ShShaderSpec spec, ShShaderOutput output);
 void DeleteCompiler(TCompiler*);
 
 #endif // _SHHANDLE_INCLUDED_
--- a/gfx/angle/src/compiler/ShaderLang.cpp
+++ b/gfx/angle/src/compiler/ShaderLang.cpp
@@ -99,28 +99,30 @@ void ShInitBuiltInResources(ShBuiltInRes
     resources->MaxVertexTextureImageUnits = 0;
     resources->MaxCombinedTextureImageUnits = 8;
     resources->MaxTextureImageUnits = 8;
     resources->MaxFragmentUniformVectors = 16;
     resources->MaxDrawBuffers = 1;
 
     // Extensions.
     resources->OES_standard_derivatives = 0;
+    resources->OES_EGL_image_external = 0;
 }
 
 //
 // Driver calls these to create and destroy compiler objects.
 //
 ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec,
+                             ShShaderOutput output,
                              const ShBuiltInResources* resources)
 {
     if (!InitThread())
         return 0;
 
-    TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec));
+    TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec, output));
     TCompiler* compiler = base->getAsCompiler();
     if (compiler == 0)
         return 0;
 
     // Generate built-in symbol table.
     if (!compiler->Init(*resources)) {
         ShDestruct(base);
         return 0;
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/TranslatorESSL.cpp
@@ -0,0 +1,40 @@
+//
+// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/TranslatorESSL.h"
+
+#include "compiler/OutputESSL.h"
+
+TranslatorESSL::TranslatorESSL(ShShaderType type, ShShaderSpec spec)
+    : TCompiler(type, spec) {
+}
+
+void TranslatorESSL::translate(TIntermNode* root) {
+    TInfoSinkBase& sink = getInfoSink().obj;
+
+    // Write built-in extension behaviors.
+    writeExtensionBehavior();
+
+    // Write emulated built-in functions if needed.
+    getBuiltInFunctionEmulator().OutputEmulatedFunctionDefinition(
+        sink, getShaderType() == SH_FRAGMENT_SHADER);
+
+    // Write translated shader.
+    TOutputESSL outputESSL(sink);
+    root->traverse(&outputESSL);
+}
+
+void TranslatorESSL::writeExtensionBehavior() {
+    TInfoSinkBase& sink = getInfoSink().obj;
+    const TExtensionBehavior& extensionBehavior = getExtensionBehavior();
+    for (TExtensionBehavior::const_iterator iter = extensionBehavior.begin();
+         iter != extensionBehavior.end(); ++iter) {
+        if (iter->second != EBhUndefined) {
+            sink << "#extension " << iter->first << " : "
+                 << getBehaviorString(iter->second) << "\n";
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/TranslatorESSL.h
@@ -0,0 +1,23 @@
+//
+// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATORESSL_H_
+#define COMPILER_TRANSLATORESSL_H_
+
+#include "compiler/ShHandle.h"
+
+class TranslatorESSL : public TCompiler {
+public:
+    TranslatorESSL(ShShaderType type, ShShaderSpec spec);
+
+protected:
+    virtual void translate(TIntermNode* root);
+
+private:
+    void writeExtensionBehavior();
+};
+
+#endif  // COMPILER_TRANSLATORESSL_H_
--- a/gfx/angle/src/compiler/TranslatorGLSL.cpp
+++ b/gfx/angle/src/compiler/TranslatorGLSL.cpp
@@ -26,12 +26,16 @@ TranslatorGLSL::TranslatorGLSL(ShShaderT
 }
 
 void TranslatorGLSL::translate(TIntermNode* root) {
     TInfoSinkBase& sink = getInfoSink().obj;
 
     // Write GLSL version.
     writeVersion(getShaderType(), root, sink);
 
+    // Write emulated built-in functions if needed.
+    getBuiltInFunctionEmulator().OutputEmulatedFunctionDefinition(
+        sink, false);
+
     // Write translated shader.
     TOutputGLSL outputGLSL(sink);
     root->traverse(&outputGLSL);
 }
--- a/gfx/angle/src/compiler/ValidateLimitations.cpp
+++ b/gfx/angle/src/compiler/ValidateLimitations.cpp
@@ -48,23 +48,16 @@ public:
     virtual void visitSymbol(TIntermSymbol* symbol) {
         // Only constants and loop indices are allowed in a
         // constant index expression.
         if (mValid) {
             mValid = (symbol->getQualifier() == EvqConst) ||
                      IsLoopIndex(symbol, mLoopStack);
         }
     }
-    virtual void visitConstantUnion(TIntermConstantUnion*) {}
-    virtual bool visitBinary(Visit, TIntermBinary*) { return true; }
-    virtual bool visitUnary(Visit, TIntermUnary*) { return true; }
-    virtual bool visitSelection(Visit, TIntermSelection*) { return true; }
-    virtual bool visitAggregate(Visit, TIntermAggregate*) { return true; }
-    virtual bool visitLoop(Visit, TIntermLoop*) { return true; }
-    virtual bool visitBranch(Visit, TIntermBranch*) { return true; }
 
 private:
     bool mValid;
     const TLoopStack& mLoopStack;
 };
 
 // Traverses a node to check if it uses a loop index.
 // If an int loop index is used in its body as a sampler array index,
@@ -89,47 +82,32 @@ public:
                 mUsesIntLoopIndex = true;
                 MarkLoopForUnroll(symbol, mLoopStack);
                 break;
               default:
                 UNREACHABLE();
             }
         }
     }
-    virtual void visitConstantUnion(TIntermConstantUnion*) {}
-    virtual bool visitBinary(Visit, TIntermBinary*) { return true; }
-    virtual bool visitUnary(Visit, TIntermUnary*) { return true; }
-    virtual bool visitSelection(Visit, TIntermSelection*) { return true; }
-    virtual bool visitAggregate(Visit, TIntermAggregate*) { return true; }
-    virtual bool visitLoop(Visit, TIntermLoop*) { return true; }
-    virtual bool visitBranch(Visit, TIntermBranch*) { return true; }
 
 private:
     bool mUsesFloatLoopIndex;
     bool mUsesIntLoopIndex;
     TLoopStack& mLoopStack;
 };
 }  // namespace
 
 ValidateLimitations::ValidateLimitations(ShShaderType shaderType,
                                          TInfoSinkBase& sink)
     : mShaderType(shaderType),
       mSink(sink),
       mNumErrors(0)
 {
 }
 
-void ValidateLimitations::visitSymbol(TIntermSymbol*)
-{
-}
-
-void ValidateLimitations::visitConstantUnion(TIntermConstantUnion*)
-{
-}
-
 bool ValidateLimitations::visitBinary(Visit, TIntermBinary* node)
 {
     // Check if loop index is modified in the loop body.
     validateOperation(node, node->getLeft());
 
     // Check indexing.
     switch (node->getOp()) {
       case EOpIndexDirect:
@@ -165,21 +143,16 @@ bool ValidateLimitations::visitBinary(Vi
 bool ValidateLimitations::visitUnary(Visit, TIntermUnary* node)
 {
     // Check if loop index is modified in the loop body.
     validateOperation(node, node->getOperand());
 
     return true;
 }
 
-bool ValidateLimitations::visitSelection(Visit, TIntermSelection*)
-{
-    return true;
-}
-
 bool ValidateLimitations::visitAggregate(Visit, TIntermAggregate* node)
 {
     switch (node->getOp()) {
       case EOpFunctionCall:
         validateFunctionCall(node);
         break;
       default:
         break;
@@ -204,21 +177,16 @@ bool ValidateLimitations::visitLoop(Visi
         body->traverse(this);
         mLoopStack.pop_back();
     }
 
     // The loop is fully processed - no need to visit children.
     return false;
 }
 
-bool ValidateLimitations::visitBranch(Visit, TIntermBranch*)
-{
-    return true;
-}
-
 void ValidateLimitations::error(TSourceLoc loc,
                                 const char *reason, const char* token)
 {
     mSink.prefix(EPrefixError);
     mSink.location(loc);
     mSink << "'" << token << "' : " << reason << "\n";
     ++mNumErrors;
 }
--- a/gfx/angle/src/compiler/ValidateLimitations.h
+++ b/gfx/angle/src/compiler/ValidateLimitations.h
@@ -20,24 +20,20 @@ typedef TVector<TLoopInfo> TLoopStack;
 // Traverses intermediate tree to ensure that the shader does not exceed the
 // minimum functionality mandated in GLSL 1.0 spec, Appendix A.
 class ValidateLimitations : public TIntermTraverser {
 public:
     ValidateLimitations(ShShaderType shaderType, TInfoSinkBase& sink);
 
     int numErrors() const { return mNumErrors; }
 
-    virtual void visitSymbol(TIntermSymbol*);
-    virtual void visitConstantUnion(TIntermConstantUnion*);
     virtual bool visitBinary(Visit, TIntermBinary*);
     virtual bool visitUnary(Visit, TIntermUnary*);
-    virtual bool visitSelection(Visit, TIntermSelection*);
     virtual bool visitAggregate(Visit, TIntermAggregate*);
     virtual bool visitLoop(Visit, TIntermLoop*);
-    virtual bool visitBranch(Visit, TIntermBranch*);
 
 private:
     void error(TSourceLoc loc, const char *reason, const char* token);
 
     bool withinLoopBody() const;
     bool isLoopIndex(const TIntermSymbol* symbol) const;
     bool validateLoopType(TIntermLoop* node);
     bool validateForLoopHeader(TIntermLoop* node, TLoopInfo* info);
--- a/gfx/angle/src/compiler/generate_glslang_lexer.sh
+++ b/gfx/angle/src/compiler/generate_glslang_lexer.sh
@@ -1,11 +0,0 @@
-#!/bin/bash
-# Copyright (c) 2010 The ANGLE Project Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Generates GLSL ES lexer - glslang_lex.cpp
-
-script_dir=$(dirname $0)
-input_file=$script_dir/glslang.l
-output_file=$script_dir/glslang_lex.cpp
-flex --noline --nounistd --outfile=$output_file $input_file
--- a/gfx/angle/src/compiler/generate_glslang_parser.sh
+++ b/gfx/angle/src/compiler/generate_glslang_parser.sh
@@ -1,12 +0,0 @@
-#!/bin/bash
-# Copyright (c) 2010 The ANGLE Project Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Generates GLSL ES parser - glslang_tab.h and glslang_tab.cpp
-
-script_dir=$(dirname $0)
-input_file=$script_dir/glslang.y
-output_header=$script_dir/glslang_tab.h
-output_source=$script_dir/glslang_tab.cpp
-bison --no-lines --skeleton=yacc.c --defines=$output_header --output=$output_source $input_file
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/generate_parser.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# Copyright (c) 2010 The ANGLE Project Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Generates GLSL ES parser - glslang_lex.cpp, glslang_tab.h, and glslang_tab.cpp
+
+run_flex()
+{
+input_file=$script_dir/$1.l
+output_source=$script_dir/$1_lex.cpp
+flex --noline --nounistd --outfile=$output_source $input_file
+}
+
+run_bison()
+{
+input_file=$script_dir/$1.y
+output_header=$script_dir/$1_tab.h
+output_source=$script_dir/$1_tab.cpp
+bison --no-lines --skeleton=yacc.c --defines=$output_header --output=$output_source $input_file
+}
+
+script_dir=$(dirname $0)
+
+# Generate Parser
+run_flex glslang
+run_bison glslang
--- a/gfx/angle/src/compiler/glslang.l
+++ b/gfx/angle/src/compiler/glslang.l
@@ -4,28 +4,28 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 This file contains the Lex specification for GLSL ES.
 Based on ANSI C grammar, Lex specification:
 http://www.lysator.liu.se/c/ANSI-C-grammar-l.html
 
-IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_glslang_lexer.sh,
+IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh,
 WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp).
 */
 
 %top{
 //
 // Copyright (c) 2010 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
-// This file is auto-generated by generate_glslang_lexer.sh. DO NOT EDIT!
+// This file is auto-generated by generate_parser.sh. DO NOT EDIT!
 }
 
 %{
 #include "compiler/glslang.h"
 #include "compiler/ParseHelper.h"
 #include "compiler/util.h"
 #include "glslang_tab.h"
 
@@ -115,16 +115,17 @@ O           [0-7]
 "ivec3"        { context->lexAfterType = true; return (IVEC3); }
 "ivec4"        { context->lexAfterType = true; return (IVEC4); }
 "bvec2"        { context->lexAfterType = true; return (BVEC2); }
 "bvec3"        { context->lexAfterType = true; return (BVEC3); }
 "bvec4"        { context->lexAfterType = true; return (BVEC4); }
 
 "sampler2D"       { context->lexAfterType = true; return SAMPLER2D; }
 "samplerCube"     { context->lexAfterType = true; return SAMPLERCUBE; }
+"samplerExternalOES" { context->lexAfterType = true; return SAMPLER_EXTERNAL_OES; }
 
 "struct"       { context->lexAfterType = true; return(STRUCT); }
 
 "asm"          { return reserved_word(yyscanner); }
 
 "class"        { return reserved_word(yyscanner); }
 "union"        { return reserved_word(yyscanner); }
 "enum"         { return reserved_word(yyscanner); }
--- a/gfx/angle/src/compiler/glslang.y
+++ b/gfx/angle/src/compiler/glslang.y
@@ -4,28 +4,28 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 This file contains the Yacc grammar for GLSL ES.
 Based on ANSI C Yacc grammar:
 http://www.lysator.liu.se/c/ANSI-C-grammar-y.html
 
-IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_glslang_parser.sh,
+IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh,
 WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
 */
 
 %{
 //
 // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
-// This file is auto-generated by generate_glslang_parser.sh. DO NOT EDIT!
+// This file is auto-generated by generate_parser.sh. DO NOT EDIT!
 
 #include "compiler/SymbolTable.h"
 #include "compiler/ParseHelper.h"
 #include "GLSLANG/ShaderLang.h"
 
 #define YYLEX_PARAM context->scanner
 %}
 
@@ -93,17 +93,17 @@ extern void yyerror(TParseContext* conte
 %}
 
 %token <lex> INVARIANT HIGH_PRECISION MEDIUM_PRECISION LOW_PRECISION PRECISION
 %token <lex> ATTRIBUTE CONST_QUAL BOOL_TYPE FLOAT_TYPE INT_TYPE
 %token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN
 %token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4
 %token <lex> MATRIX2 MATRIX3 MATRIX4 IN_QUAL OUT_QUAL INOUT_QUAL UNIFORM VARYING
 %token <lex> STRUCT VOID_TYPE WHILE
-%token <lex> SAMPLER2D SAMPLERCUBE
+%token <lex> SAMPLER2D SAMPLERCUBE SAMPLER_EXTERNAL_OES
 
 %token <lex> IDENTIFIER TYPE_NAME FLOATCONSTANT INTCONSTANT BOOLCONSTANT
 %token <lex> FIELD_SELECTION
 %token <lex> LEFT_OP RIGHT_OP
 %token <lex> INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP
 %token <lex> AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN
 %token <lex> MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN
 %token <lex> SUB_ASSIGN
@@ -586,27 +586,20 @@ function_call_header
     : function_identifier LEFT_PAREN {
         $$ = $1;
     }
     ;
 
 // Grammar Note:  Constructors look like functions, but are recognized as types.
 
 function_identifier
-    : type_specifier {
+    : type_specifier_nonarray {
         //
         // Constructor
         //
-        if ($1.array) {
-            // Constructors for arrays are not allowed.
-            context->error($1.line, "cannot construct this type", "array", "");
-            context->recover();
-            $1.setArray(false);
-        }
-
         TOperator op = EOpNull;
         if ($1.userDef) {
             op = EOpConstructStruct;
         } else {
             switch ($1.type) {
             case EbtFloat:
                 if ($1.matrix) {
                     switch($1.size) {
@@ -1171,23 +1164,16 @@ parameter_type_specifier
         TParameter param = { 0, new TType($1) };
         $$.param = param;
     }
     ;
 
 init_declarator_list
     : single_declaration {
         $$ = $1;
-        
-        if ($$.type.precision == EbpUndefined) {
-            $$.type.precision = context->symbolTable.getDefaultPrecision($1.type.type);
-            if (context->precisionErrorCheck($1.line, $$.type.precision, $1.type.type)) {
-                context->recover();
-            }
-        }
     }
     | init_declarator_list COMMA IDENTIFIER {
         TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$3.string, TType($1.type), $3.line);
         $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, symbol, $3.line);
         
         if (context->structQualifierErrorCheck($3.line, $$.type))
             context->recover();
 
@@ -1485,16 +1471,23 @@ type_qualifier
             context->recover();
         $$.setBasic(EbtVoid, EvqUniform, $1.line);
     }
     ;
 
 type_specifier
     : type_specifier_no_prec {
         $$ = $1;
+
+        if ($$.precision == EbpUndefined) {
+            $$.precision = context->symbolTable.getDefaultPrecision($1.type);
+            if (context->precisionErrorCheck($1.line, $$.precision, $1.type)) {
+                context->recover();
+            }
+        }
     }
     | precision_qualifier type_specifier_no_prec {
         $$ = $2;
         $$.precision = $1;
     }
     ;
 
 precision_qualifier
@@ -1617,16 +1610,25 @@ type_specifier_nonarray
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         $$.setBasic(EbtSampler2D, qual, $1.line);
     }
     | SAMPLERCUBE {
         FRAG_VERT_ONLY("samplerCube", $1.line);
         TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         $$.setBasic(EbtSamplerCube, qual, $1.line);
     }
+    | SAMPLER_EXTERNAL_OES {
+        if (!context->supportsExtension("GL_OES_EGL_image_external")) {
+            context->error($1.line, "unsupported type", "samplerExternalOES", "");
+            context->recover();
+        }
+        FRAG_VERT_ONLY("samplerExternalOES", $1.line);
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtSamplerExternalOES, qual, $1.line);
+    }
     | struct_specifier {
         FRAG_VERT_ONLY("struct", $1.line);
         $$ = $1;
         $$.qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
     }
     | TYPE_NAME {
         //
         // This is for user defined type names.  The lexical phase looked up the
@@ -1688,16 +1690,17 @@ struct_declaration
         for (unsigned int i = 0; i < $$->size(); ++i) {
             //
             // Careful not to replace already known aspects of type, like array-ness
             //
             TType* type = (*$$)[i].type;
             type->setBasicType($1.type);
             type->setNominalSize($1.size);
             type->setMatrix($1.matrix);
+            type->setPrecision($1.precision);
 
             // don't allow arrays of arrays
             if (type->isArray()) {
                 if (context->arrayTypeErrorCheck($1.line, $1))
                     context->recover();
             }
             if ($1.array)
                 type->setArraySize($1.arraySize);
--- a/gfx/angle/src/compiler/glslang_lex.cpp
+++ b/gfx/angle/src/compiler/glslang_lex.cpp
@@ -1,16 +1,16 @@
 #line 17 "compiler/glslang.l"
 //
 // Copyright (c) 2010 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
-// This file is auto-generated by generate_glslang_lexer.sh. DO NOT EDIT!
+// This file is auto-generated by generate_parser.sh. DO NOT EDIT!
 
 
 
 #line 13 "compiler/glslang_lex.cpp"
 
 #define  YY_INT_ALIGNED short int
 
 /* A lexical scanner generated by flex */
@@ -366,382 +366,390 @@ static void yy_fatal_error (yyconst char
  */
 #define YY_DO_BEFORE_ACTION \
 	yyg->yytext_ptr = yy_bp; \
 	yyleng = (size_t) (yy_cp - yy_bp); \
 	yyg->yy_hold_char = *yy_cp; \
 	*yy_cp = '\0'; \
 	yyg->yy_c_buf_p = yy_cp;
 
-#define YY_NUM_RULES 145
-#define YY_END_OF_BUFFER 146
+#define YY_NUM_RULES 146
+#define YY_END_OF_BUFFER 147
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
 	{
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static yyconst flex_int16_t yy_accept[411] =
+static yyconst flex_int16_t yy_accept[422] =
     {   0,
-        0,    0,    0,    0,    0,    0,  146,  144,  143,  143,
-      128,  134,  139,  123,  124,  132,  131,  120,  129,  127,
-      133,   92,   92,  121,  117,  135,  122,  136,  140,   88,
-      125,  126,  138,   88,   88,   88,   88,   88,   88,   88,
-       88,   88,   88,   88,   88,   88,   88,   88,   88,   88,
-       88,   88,   88,  118,  137,  119,  130,    3,    4,    3,
-      142,  145,  141,  114,  100,  119,  108,  103,   98,  106,
-       96,  107,   97,   95,    2,    1,   99,   94,   90,   91,
-        0,    0,   92,  126,  118,  125,  115,  111,  113,  112,
-      116,   88,  104,  110,   88,   88,   88,   88,   88,   88,
-
-       88,   88,   88,   88,   17,   88,   88,   88,   88,   88,
-       88,   88,   88,   88,   88,   88,   88,   88,   20,   22,
-       88,   88,   88,   88,   88,   88,   88,   88,   88,   88,
-       88,   88,   88,   88,   88,   88,   88,   88,   88,   88,
-       88,   88,   88,   88,   88,   88,  105,  109,    5,  141,
-        0,    1,   94,    0,    0,   93,   89,  101,  102,   48,
-       88,   88,   88,   88,   88,   88,   88,   88,   88,   88,
-       88,   88,   88,   88,   88,   88,   88,   18,   88,   88,
-       88,   88,   88,   88,   88,   88,   26,   88,   88,   88,
-       88,   88,   88,   88,   88,   23,   88,   88,   88,   88,
-
-       88,   88,   88,   88,   88,   88,   88,   88,   88,   88,
-       88,   88,   88,   88,   88,   88,   88,   88,    0,   95,
-        0,   94,   88,   28,   88,   88,   85,   88,   88,   88,
-       88,   88,   88,   88,   21,   51,   88,   88,   88,   88,
-       88,   56,   70,   88,   88,   88,   88,   88,   88,   88,
-       88,   67,    9,   33,   34,   35,   88,   88,   88,   88,
-       88,   88,   88,   88,   88,   88,   88,   88,   88,   88,
-       88,   54,   29,   88,   88,   88,   88,   88,   88,   36,
-       37,   38,   27,   88,   88,   88,   15,   42,   43,   44,
-       49,   12,   88,   88,   88,   88,   81,   82,   83,   88,
-
-       30,   71,   25,   78,   79,   80,    7,   75,   76,   77,
-       88,   24,   73,   88,   88,   39,   40,   41,   88,   88,
-       88,   88,   88,   88,   88,   88,   88,   68,   88,   88,
-       88,   88,   88,   88,   88,   50,   88,   87,   88,   88,
-       19,   88,   88,   88,   88,   69,   64,   59,   88,   88,
-       88,   88,   88,   74,   55,   88,   62,   32,   88,   84,
-       63,   47,   57,   88,   88,   88,   88,   88,   88,   88,
-       88,   58,   31,   88,   88,   88,    8,   88,   88,   88,
-       88,   88,   52,   13,   88,   14,   88,   88,   16,   65,
-       88,   88,   88,   60,   88,   88,   88,   53,   72,   61,
-
-       11,   66,    6,   86,   10,   45,   88,   88,   46,    0
+        0,    0,    0,    0,    0,    0,  147,  145,  144,  144,
+      129,  135,  140,  124,  125,  133,  132,  121,  130,  128,
+      134,   93,   93,  122,  118,  136,  123,  137,  141,   89,
+      126,  127,  139,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,  119,  138,  120,  131,    3,    4,    3,
+      143,  146,  142,  115,  101,  120,  109,  104,   99,  107,
+       97,  108,   98,   96,    2,    1,  100,   95,   91,   92,
+        0,    0,   93,  127,  119,  126,  116,  112,  114,  113,
+      117,   89,  105,  111,   89,   89,   89,   89,   89,   89,
+
+       89,   89,   89,   89,   17,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   89,   20,   22,
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,  106,  110,    5,  142,
+        0,    1,   95,    0,    0,   94,   90,  102,  103,   49,
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   18,   89,   89,
+       89,   89,   89,   89,   89,   89,   26,   89,   89,   89,
+       89,   89,   89,   89,   89,   23,   89,   89,   89,   89,
+
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   89,    0,   96,
+        0,   95,   89,   28,   89,   89,   86,   89,   89,   89,
+       89,   89,   89,   89,   21,   52,   89,   89,   89,   89,
+       89,   57,   71,   89,   89,   89,   89,   89,   89,   89,
+       89,   68,    9,   33,   34,   35,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   55,   29,   89,   89,   89,   89,   89,   89,   36,
+       37,   38,   27,   89,   89,   89,   15,   42,   43,   44,
+       50,   12,   89,   89,   89,   89,   82,   83,   84,   89,
+
+       30,   72,   25,   79,   80,   81,    7,   76,   77,   78,
+       89,   24,   74,   89,   89,   39,   40,   41,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   69,   89,   89,
+       89,   89,   89,   89,   89,   51,   89,   88,   89,   89,
+       19,   89,   89,   89,   89,   70,   65,   60,   89,   89,
+       89,   89,   89,   75,   56,   89,   63,   32,   89,   85,
+       64,   48,   58,   89,   89,   89,   89,   89,   89,   89,
+       89,   59,   31,   89,   89,   89,    8,   89,   89,   89,
+       89,   89,   53,   13,   89,   14,   89,   89,   16,   66,
+       89,   89,   89,   61,   89,   89,   89,   89,   54,   73,
+
+       62,   11,   67,    6,   87,   10,   45,   89,   89,   89,
+       89,   46,   89,   89,   89,   89,   89,   89,   89,   47,
+        0
     } ;
 
 static yyconst flex_int32_t yy_ec[256] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
         2,    2,    2,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    2,    4,    1,    1,    1,    5,    6,    1,    7,
         8,    9,   10,   11,   12,   13,   14,   15,   16,   17,
        18,   19,   16,   16,   16,   20,   20,   21,   22,   23,
        24,   25,   26,    1,   27,   27,   28,   29,   30,   27,
-       31,   31,   31,   31,   31,   31,   31,   31,   31,   31,
-       31,   31,   31,   31,   31,   31,   31,   32,   31,   31,
-       33,    1,   34,   35,   31,    1,   36,   37,   38,   39,
-
-       40,   41,   42,   43,   44,   31,   45,   46,   47,   48,
-       49,   50,   31,   51,   52,   53,   54,   55,   56,   57,
-       58,   59,   60,   61,   62,   63,    1,    1,    1,    1,
+       31,   31,   31,   31,   31,   31,   31,   31,   32,   31,
+       31,   31,   33,   31,   31,   31,   31,   34,   31,   31,
+       35,    1,   36,   37,   31,    1,   38,   39,   40,   41,
+
+       42,   43,   44,   45,   46,   31,   47,   48,   49,   50,
+       51,   52,   31,   53,   54,   55,   56,   57,   58,   59,
+       60,   61,   62,   63,   64,   65,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1
     } ;
 
-static yyconst flex_int32_t yy_meta[64] =
+static yyconst flex_int32_t yy_meta[66] =
     {   0,
         1,    1,    2,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    3,    3,    3,    3,    3,    3,
         1,    1,    1,    1,    1,    1,    3,    3,    3,    3,
-        4,    4,    1,    1,    1,    3,    3,    3,    3,    3,
-        3,    4,    4,    4,    4,    4,    4,    4,    4,    4,
-        4,    4,    4,    4,    4,    4,    4,    4,    4,    1,
-        1,    1,    1
+        4,    4,    4,    4,    1,    1,    1,    3,    3,    3,
+        3,    3,    3,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    1,    1,    1,    1
     } ;
 
-static yyconst flex_int16_t yy_base[416] =
+static yyconst flex_int16_t yy_base[427] =
     {   0,
-        0,    0,   61,   62,   71,    0,  606,  607,  607,  607,
-      581,   42,  129,  607,  607,  580,  126,  607,  125,  123,
-      137,  149,  157,  578,  607,  175,  578,   44,  607,    0,
-      607,  607,  120,   95,  103,  142,  146,  136,  156,  552,
-      168,  162,  551,  120,  158,  545,  173,  558,  172,  178,
-      111,  186,  554,  607,  159,  607,  607,  607,  607,  582,
-      607,  607,    0,  607,  607,  607,  607,  607,  607,  607,
-      607,  607,  607,  222,  607,    0,  607,  228,  254,  262,
-      281,    0,  290,  607,  607,  607,  571,  607,  607,  607,
-      570,    0,  607,  607,  546,  539,  542,  550,  549,  536,
-
-      551,  538,  544,  532,  529,  542,  529,  526,  526,  532,
-      520,  527,  524,  534,  520,  526,  529,  530,    0,  204,
-      529,  207,  515,  528,  519,  521,  511,  525,  522,  524,
-      507,  512,  509,  498,  183,  512,  508,  510,  499,  502,
-      212,  507,  499,  511,  186,  504,  607,  607,  607,    0,
-      306,    0,  316,  332,  270,  342,    0,  607,  607,    0,
-      496,  500,  509,  506,  490,  490,  161,  505,  502,  502,
-      500,  497,  489,  495,  482,  493,  496,    0,  493,  481,
-      488,  485,  489,  482,  471,  470,  483,  486,  483,  478,
-      469,  294,  474,  477,  468,  465,  469,  475,  466,  457,
-
-      460,  458,  468,  454,  452,  452,  454,  451,  462,  461,
-      278,  456,  451,  440,  320,  458,  460,  449,  348,  354,
-      360,  366,  450,    0,  448,  336,    0,  440,  438,  446,
-      435,  452,  441,  370,    0,    0,  435,  445,  445,  430,
-      373,    0,    0,  432,  376,  433,  427,  426,  427,  426,
-      379,    0,    0,    0,    0,    0,  422,  423,  428,  419,
-      432,  427,  426,  418,  422,  414,  417,  421,  426,  425,
-      416,    0,    0,  422,  411,  411,  416,  415,  412,    0,
-        0,    0,    0,  402,  414,  416,    0,    0,    0,    0,
-        0,    0,  404,  405,  399,  409,    0,    0,    0,  400,
+        0,    0,   63,   64,   73,    0,  621,  622,  622,  622,
+      596,   44,  133,  622,  622,  595,  130,  622,  129,  127,
+      141,  153,  161,  593,  622,  177,  593,   46,  622,    0,
+      622,  622,  124,   97,  105,  137,  148,  154,  168,  565,
+      151,  167,  564,  121,  158,  558,  111,  571,  177,  176,
+      157,  188,  567,  622,  168,  622,  622,  622,  622,  597,
+      622,  622,    0,  622,  622,  622,  622,  622,  622,  622,
+      622,  622,  622,  225,  622,    0,  622,  231,  259,  267,
+      288,    0,  297,  622,  622,  622,  586,  622,  622,  622,
+      585,    0,  622,  622,  559,  552,  555,  563,  562,  549,
+
+      564,  551,  557,  545,  542,  555,  542,  539,  539,  545,
+      533,  540,  537,  547,  533,  539,  542,  543,    0,  205,
+      542,  170,  528,  541,  532,  534,  524,  538,  535,  537,
+      520,  525,  522,  511,  199,  525,  521,  523,  512,  515,
+      212,  520,  512,  524,  138,  517,  622,  622,  622,    0,
+      313,    0,  325,  341,  275,  353,    0,  622,  622,    0,
+      509,  513,  522,  519,  503,  503,  179,  518,  515,  515,
+      513,  510,  502,  508,  495,  506,  509,    0,  506,  494,
+      501,  498,  502,  495,  484,  483,  496,  499,  496,  491,
+      482,  246,  487,  490,  481,  478,  482,  488,  479,  470,
+
+      473,  471,  481,  467,  465,  465,  467,  464,  475,  474,
+      245,  469,  464,  453,  251,  471,  473,  462,  359,  365,
+      371,  377,  463,    0,  461,  301,    0,  453,  451,  459,
+      448,  465,  454,  317,    0,    0,  448,  458,  458,  443,
+      329,    0,    0,  445,  345,  446,  440,  439,  440,  439,
+      381,    0,    0,    0,    0,    0,  435,  436,  441,  432,
+      445,  440,  439,  431,  435,  427,  430,  434,  439,  438,
+      429,    0,    0,  435,  424,  424,  429,  428,  425,    0,
+        0,    0,    0,  415,  427,  429,    0,    0,    0,    0,
+        0,    0,  417,  418,  412,  422,    0,    0,    0,  413,
 
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-      407,    0,    0,  405,  401,    0,    0,    0,  397,  393,
-      398,  388,  401,  387,  400,  389,  396,    0,  394,  396,
-      380,  389,  395,  390,  378,    0,  380,    0,  379,  382,
-        0,  371,  370,  370,  383,    0,  385,    0,  384,  383,
-      368,  381,  368,    0,    0,  371,    0,    0,  363,    0,
-        0,    0,    0,  360,  371,  364,  368,  303,  297,  288,
-      300,    0,    0,  283,  290,  269,    0,  277,  274,  255,
-      232,  255,    0,    0,  244,    0,  236,  226,    0,    0,
-      225,  208,  211,    0,  185,  202,  131,    0,    0,    0,
-
-        0,    0,    0,    0,    0,    0,  134,  117,    0,  607,
-      398,  400,  402,  406,  142
+      420,    0,    0,  418,  414,    0,    0,    0,  410,  406,
+      411,  401,  414,  400,  413,  402,  409,    0,  407,  409,
+      393,  402,  408,  403,  391,    0,  393,    0,  392,  395,
+        0,  384,  383,  383,  396,    0,  398,    0,  397,  396,
+      381,  394,  381,    0,    0,  384,    0,    0,  376,    0,
+        0,    0,    0,  373,  384,  377,  383,  380,  375,  367,
+      379,    0,    0,  372,  379,  368,    0,  377,  374,  364,
+      294,  372,    0,    0,  372,    0,  368,  324,    0,    0,
+      323,  299,  310,    0,  300,  320,  282,  278,    0,    0,
+
+        0,    0,    0,    0,    0,    0,    0,  287,  266,  260,
+      257,    0,  228,  221,  221,  206,  206,  197,  160,    0,
+      622,  400,  402,  404,  408,  157
     } ;
 
-static yyconst flex_int16_t yy_def[416] =
+static yyconst flex_int16_t yy_def[427] =
     {   0,
-      410,    1,  411,  411,  410,    5,  410,  410,  410,  410,
-      410,  410,  410,  410,  410,  410,  410,  410,  410,  410,
-      410,  410,  410,  410,  410,  410,  410,  410,  410,  412,
-      410,  410,  410,  412,  412,  412,  412,  412,  412,  412,
-      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
-      412,  412,  412,  410,  410,  410,  410,  410,  410,  410,
-      410,  410,  413,  410,  410,  410,  410,  410,  410,  410,
-      410,  410,  410,  410,  410,  414,  410,  410,  410,  410,
-      410,  415,  410,  410,  410,  410,  410,  410,  410,  410,
-      410,  412,  410,  410,  412,  412,  412,  412,  412,  412,
-
-      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
-      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
-      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
-      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
-      412,  412,  412,  412,  412,  412,  410,  410,  410,  413,
-      410,  414,  410,  410,  410,  410,  415,  410,  410,  412,
-      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
-      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
-      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
-      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
-
-      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
-      412,  412,  412,  412,  412,  412,  412,  412,  410,  410,
-      410,  410,  412,  412,  412,  412,  412,  412,  412,  412,
-      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
-      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
-      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
-      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
-      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
-      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
-      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
-
-      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
-      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
-      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
-      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
-      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
-      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
-      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
-      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
-      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
-      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
-
-      412,  412,  412,  412,  412,  412,  412,  412,  412,    0,
-      410,  410,  410,  410,  410
+      421,    1,  422,  422,  421,    5,  421,  421,  421,  421,
+      421,  421,  421,  421,  421,  421,  421,  421,  421,  421,
+      421,  421,  421,  421,  421,  421,  421,  421,  421,  423,
+      421,  421,  421,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  421,  421,  421,  421,  421,  421,  421,
+      421,  421,  424,  421,  421,  421,  421,  421,  421,  421,
+      421,  421,  421,  421,  421,  425,  421,  421,  421,  421,
+      421,  426,  421,  421,  421,  421,  421,  421,  421,  421,
+      421,  423,  421,  421,  423,  423,  423,  423,  423,  423,
+
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  421,  421,  421,  424,
+      421,  425,  421,  421,  421,  421,  426,  421,  421,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  421,  421,
+      421,  421,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+        0,  421,  421,  421,  421,  421
     } ;
 
-static yyconst flex_int16_t yy_nxt[671] =
+static yyconst flex_int16_t yy_nxt[688] =
     {   0,
         8,    9,   10,   11,   12,   13,   14,   15,   16,   17,
        18,   19,   20,   21,   22,   23,   23,   23,   23,   23,
        24,   25,   26,   27,   28,   29,   30,   30,   30,   30,
-       30,   30,   31,   32,   33,   34,   35,   36,   37,   38,
-       39,   40,   41,   42,   30,   43,   44,   45,   46,   47,
-       48,   49,   50,   51,   52,   53,   30,   30,   30,   54,
-       55,   56,   57,   59,   59,   65,   66,   90,   91,   60,
-       60,    8,   61,   62,    8,    8,    8,    8,    8,    8,
+       30,   30,   30,   30,   31,   32,   33,   34,   35,   36,
+       37,   38,   39,   40,   41,   42,   30,   43,   44,   45,
+       46,   47,   48,   49,   50,   51,   52,   53,   30,   30,
+       30,   54,   55,   56,   57,   59,   59,   65,   66,   90,
+       91,   60,   60,    8,   61,   62,    8,    8,    8,    8,
         8,    8,    8,    8,    8,    8,    8,    8,    8,    8,
-        8,    8,    8,    8,    8,    8,    8,   63,   63,   63,
-
-       63,   63,   63,    8,    8,    8,   63,   63,   63,   63,
+        8,    8,    8,    8,    8,    8,    8,    8,    8,   63,
+
+       63,   63,   63,   63,   63,   63,   63,    8,    8,    8,
        63,   63,   63,   63,   63,   63,   63,   63,   63,   63,
        63,   63,   63,   63,   63,   63,   63,   63,   63,   63,
-        8,    8,    8,    8,   67,   70,   72,   74,   74,   74,
-       74,   74,   74,   93,  157,   75,   95,   96,   73,   71,
-       76,   97,   68,   98,   94,  123,  409,   99,  141,  124,
-       77,   78,  142,   79,   79,   79,   79,   79,   80,   78,
-      408,   83,   83,   83,   83,   83,   83,  100,   81,   85,
-       82,  107,  147,  108,  407,  103,   81,  101,   81,  104,
-      102,  110,  109,  125,  105,   86,   81,   87,   88,  111,
-
-      106,  112,  119,  116,  113,   82,  126,  132,  128,  120,
-      114,  117,  229,  230,  133,  134,  121,  137,  204,  148,
-      138,  143,  118,  129,  135,  144,  130,  136,  139,  216,
-      406,  217,  405,  205,  145,  140,   74,   74,   74,   74,
-       74,   74,  153,  153,  153,  153,  153,  153,  396,  184,
-      404,  151,  185,  186,  190,  211,  187,  154,  188,  397,
-      403,  151,  191,  212,  402,  401,   78,  154,   79,   79,
-       79,   79,   79,   80,   78,  400,   80,   80,   80,   80,
-       80,   80,  399,   81,  156,  156,  156,  156,  156,  156,
-      155,   81,  155,   81,  398,  156,  156,  156,  156,  156,
-
-      156,   81,   78,  395,   83,   83,   83,   83,   83,   83,
-      254,  255,  256,  394,  393,  219,  392,  219,  275,   81,
-      220,  220,  220,  220,  220,  220,  276,  391,  390,   81,
-      153,  153,  153,  153,  153,  153,  280,  281,  282,  389,
-      388,  221,  387,  221,  386,  154,  222,  222,  222,  222,
-      222,  222,  288,  289,  290,  154,  156,  156,  156,  156,
-      156,  156,  220,  220,  220,  220,  220,  220,  220,  220,
-      220,  220,  220,  220,  222,  222,  222,  222,  222,  222,
-      222,  222,  222,  222,  222,  222,  297,  298,  299,  304,
-      305,  306,  308,  309,  310,  316,  317,  318,   58,   58,
-
-       58,   58,   92,   92,  150,  150,  152,  385,  152,  152,
-      384,  383,  382,  381,  380,  379,  378,  377,  376,  375,
-      374,  373,  372,  371,  370,  369,  368,  367,  366,  365,
-      364,  363,  362,  361,  360,  359,  358,  357,  356,  355,
-      354,  353,  352,  351,  350,  349,  348,  347,  346,  345,
-      344,  343,  342,  341,  340,  339,  338,  337,  336,  335,
-      334,  333,  332,  331,  330,  329,  328,  327,  326,  325,
-      324,  323,  322,  321,  320,  319,  315,  314,  313,  312,
-      311,  307,  303,  302,  301,  300,  296,  295,  294,  293,
-      292,  291,  287,  286,  285,  284,  283,  279,  278,  277,
-
-      274,  273,  272,  271,  270,  269,  268,  267,  266,  265,
-      264,  263,  262,  261,  260,  259,  258,  257,  253,  252,
-      251,  250,  249,  248,  247,  246,  245,  244,  243,  242,
-      241,  240,  239,  238,  237,  236,  235,  234,  233,  232,
-      231,  228,  227,  226,  225,  224,  223,  218,  215,  214,
-      213,  210,  209,  208,  207,  206,  203,  202,  201,  200,
-      199,  198,  197,  196,  195,  194,  193,  192,  189,  183,
-      182,  181,  180,  179,  178,  177,  176,  175,  174,  173,
-      172,  171,  170,  169,  168,  167,  166,  165,  164,  163,
-      162,  161,  160,  159,  158,  149,  146,  131,  127,  122,
-
-      115,   89,   84,   69,   64,  410,    7,  410,  410,  410,
-      410,  410,  410,  410,  410,  410,  410,  410,  410,  410,
-      410,  410,  410,  410,  410,  410,  410,  410,  410,  410,
-      410,  410,  410,  410,  410,  410,  410,  410,  410,  410,
-      410,  410,  410,  410,  410,  410,  410,  410,  410,  410,
-      410,  410,  410,  410,  410,  410,  410,  410,  410,  410,
-      410,  410,  410,  410,  410,  410,  410,  410,  410,  410
+       63,   63,   63,   63,    8,    8,    8,    8,   67,   70,
+       72,   74,   74,   74,   74,   74,   74,   93,  128,   75,
+       95,   96,   73,   71,   76,   97,   68,   98,  123,  157,
+       94,   99,  124,  129,   77,   78,  130,   79,   79,   79,
+       79,   79,   80,   78,  100,   83,   83,   83,   83,   83,
+       83,   85,   81,  216,  101,  217,   82,  102,  116,  103,
+       81,  147,  420,  104,   81,  125,  117,   86,  105,   87,
+
+       88,  107,   81,  108,  106,  110,  141,  118,  126,  119,
+      142,   82,  109,  111,  132,  112,  120,  137,  113,  190,
+      138,  133,  134,  121,  114,  143,  419,  191,  139,  144,
+      148,  135,  229,  230,  136,  140,  204,  418,  145,   74,
+       74,   74,   74,   74,   74,  153,  153,  153,  153,  153,
+      153,  205,  184,  417,  151,  185,  186,  211,  416,  187,
+      154,  188,  254,  255,  256,  212,  151,  280,  281,  282,
+      415,   78,  154,   79,   79,   79,   79,   79,   80,   78,
+      414,   80,   80,   80,   80,   80,   80,  275,   81,  156,
+      156,  156,  156,  156,  156,  276,   81,  155,  413,  155,
+
+       81,  412,  156,  156,  156,  156,  156,  156,   81,   78,
+      396,   83,   83,   83,   83,   83,   83,  288,  289,  290,
+      411,  397,  219,  398,  219,  410,   81,  220,  220,  220,
+      220,  220,  220,  297,  298,  299,  409,  408,   81,  153,
+      153,  153,  153,  153,  153,  304,  305,  306,  407,  406,
+      221,  405,  221,  404,  154,  222,  222,  222,  222,  222,
+      222,  308,  309,  310,  403,  402,  154,  156,  156,  156,
+      156,  156,  156,  220,  220,  220,  220,  220,  220,  220,
+      220,  220,  220,  220,  220,  222,  222,  222,  222,  222,
+      222,  222,  222,  222,  222,  222,  222,  316,  317,  318,
+
+       58,   58,   58,   58,   92,   92,  150,  150,  152,  401,
+      152,  152,  400,  399,  395,  394,  393,  392,  391,  390,
+      389,  388,  387,  386,  385,  384,  383,  382,  381,  380,
+      379,  378,  377,  376,  375,  374,  373,  372,  371,  370,
+      369,  368,  367,  366,  365,  364,  363,  362,  361,  360,
+      359,  358,  357,  356,  355,  354,  353,  352,  351,  350,
+      349,  348,  347,  346,  345,  344,  343,  342,  341,  340,
+      339,  338,  337,  336,  335,  334,  333,  332,  331,  330,
+      329,  328,  327,  326,  325,  324,  323,  322,  321,  320,
+      319,  315,  314,  313,  312,  311,  307,  303,  302,  301,
+
+      300,  296,  295,  294,  293,  292,  291,  287,  286,  285,
+      284,  283,  279,  278,  277,  274,  273,  272,  271,  270,
+      269,  268,  267,  266,  265,  264,  263,  262,  261,  260,
+      259,  258,  257,  253,  252,  251,  250,  249,  248,  247,
+      246,  245,  244,  243,  242,  241,  240,  239,  238,  237,
+      236,  235,  234,  233,  232,  231,  228,  227,  226,  225,
+      224,  223,  218,  215,  214,  213,  210,  209,  208,  207,
+      206,  203,  202,  201,  200,  199,  198,  197,  196,  195,
+      194,  193,  192,  189,  183,  182,  181,  180,  179,  178,
+      177,  176,  175,  174,  173,  172,  171,  170,  169,  168,
+
+      167,  166,  165,  164,  163,  162,  161,  160,  159,  158,
+      149,  146,  131,  127,  122,  115,   89,   84,   69,   64,
+      421,    7,  421,  421,  421,  421,  421,  421,  421,  421,
+      421,  421,  421,  421,  421,  421,  421,  421,  421,  421,
+      421,  421,  421,  421,  421,  421,  421,  421,  421,  421,
+      421,  421,  421,  421,  421,  421,  421,  421,  421,  421,
+      421,  421,  421,  421,  421,  421,  421,  421,  421,  421,
+      421,  421,  421,  421,  421,  421,  421,  421,  421,  421,
+      421,  421,  421,  421,  421,  421,  421
     } ;
 
-static yyconst flex_int16_t yy_chk[671] =
+static yyconst flex_int16_t yy_chk[688] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    3,    4,   12,   12,   28,   28,    3,
-        4,    5,    5,    5,    5,    5,    5,    5,    5,    5,
+        1,    1,    1,    1,    1,    3,    4,   12,   12,   28,
+       28,    3,    4,    5,    5,    5,    5,    5,    5,    5,
         5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
         5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
 
         5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
         5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
         5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
-        5,    5,    5,    5,   13,   17,   19,   20,   20,   20,
-       20,   20,   20,   33,  415,   21,   34,   34,   19,   17,
-       21,   35,   13,   35,   33,   44,  408,   35,   51,   44,
-       21,   22,   51,   22,   22,   22,   22,   22,   22,   23,
-      407,   23,   23,   23,   23,   23,   23,   36,   22,   26,
-       22,   38,   55,   38,  397,   37,   23,   36,   22,   37,
-       36,   39,   38,   45,   37,   26,   23,   26,   26,   39,
-
-       37,   39,   42,   41,   39,   22,   45,   49,   47,   42,
-       39,   41,  167,  167,   49,   49,   42,   50,  135,   55,
-       50,   52,   41,   47,   49,   52,   47,   49,   50,  145,
-      396,  145,  395,  135,   52,   50,   74,   74,   74,   74,
-       74,   74,   78,   78,   78,   78,   78,   78,  381,  120,
-      393,   74,  120,  120,  122,  141,  120,   78,  120,  381,
-      392,   74,  122,  141,  391,  388,   79,   78,   79,   79,
-       79,   79,   79,   79,   80,  387,   80,   80,   80,   80,
-       80,   80,  385,   79,  155,  155,  155,  155,  155,  155,
-       81,   80,   81,   79,  382,   81,   81,   81,   81,   81,
-
-       81,   80,   83,  380,   83,   83,   83,   83,   83,   83,
-      192,  192,  192,  379,  378,  151,  376,  151,  211,   83,
-      151,  151,  151,  151,  151,  151,  211,  375,  374,   83,
-      153,  153,  153,  153,  153,  153,  215,  215,  215,  371,
-      370,  154,  369,  154,  368,  153,  154,  154,  154,  154,
-      154,  154,  226,  226,  226,  153,  156,  156,  156,  156,
-      156,  156,  219,  219,  219,  219,  219,  219,  220,  220,
-      220,  220,  220,  220,  221,  221,  221,  221,  221,  221,
-      222,  222,  222,  222,  222,  222,  234,  234,  234,  241,
-      241,  241,  245,  245,  245,  251,  251,  251,  411,  411,
-
-      411,  411,  412,  412,  413,  413,  414,  367,  414,  414,
-      366,  365,  364,  359,  356,  353,  352,  351,  350,  349,
-      347,  345,  344,  343,  342,  340,  339,  337,  335,  334,
-      333,  332,  331,  330,  329,  327,  326,  325,  324,  323,
-      322,  321,  320,  319,  315,  314,  311,  300,  296,  295,
-      294,  293,  286,  285,  284,  279,  278,  277,  276,  275,
-      274,  271,  270,  269,  268,  267,  266,  265,  264,  263,
-      262,  261,  260,  259,  258,  257,  250,  249,  248,  247,
-      246,  244,  240,  239,  238,  237,  233,  232,  231,  230,
-      229,  228,  225,  223,  218,  217,  216,  214,  213,  212,
-
-      210,  209,  208,  207,  206,  205,  204,  203,  202,  201,
-      200,  199,  198,  197,  196,  195,  194,  193,  191,  190,
-      189,  188,  187,  186,  185,  184,  183,  182,  181,  180,
-      179,  177,  176,  175,  174,  173,  172,  171,  170,  169,
-      168,  166,  165,  164,  163,  162,  161,  146,  144,  143,
-      142,  140,  139,  138,  137,  136,  134,  133,  132,  131,
-      130,  129,  128,  127,  126,  125,  124,  123,  121,  118,
-      117,  116,  115,  114,  113,  112,  111,  110,  109,  108,
-      107,  106,  105,  104,  103,  102,  101,  100,   99,   98,
-       97,   96,   95,   91,   87,   60,   53,   48,   46,   43,
-
-       40,   27,   24,   16,   11,    7,  410,  410,  410,  410,
-      410,  410,  410,  410,  410,  410,  410,  410,  410,  410,
-      410,  410,  410,  410,  410,  410,  410,  410,  410,  410,
-      410,  410,  410,  410,  410,  410,  410,  410,  410,  410,
-      410,  410,  410,  410,  410,  410,  410,  410,  410,  410,
-      410,  410,  410,  410,  410,  410,  410,  410,  410,  410,
-      410,  410,  410,  410,  410,  410,  410,  410,  410,  410
+        5,    5,    5,    5,    5,    5,    5,    5,   13,   17,
+       19,   20,   20,   20,   20,   20,   20,   33,   47,   21,
+       34,   34,   19,   17,   21,   35,   13,   35,   44,  426,
+       33,   35,   44,   47,   21,   22,   47,   22,   22,   22,
+       22,   22,   22,   23,   36,   23,   23,   23,   23,   23,
+       23,   26,   22,  145,   36,  145,   22,   36,   41,   37,
+       23,   55,  419,   37,   22,   45,   41,   26,   37,   26,
+
+       26,   38,   23,   38,   37,   39,   51,   41,   45,   42,
+       51,   22,   38,   39,   49,   39,   42,   50,   39,  122,
+       50,   49,   49,   42,   39,   52,  418,  122,   50,   52,
+       55,   49,  167,  167,   49,   50,  135,  417,   52,   74,
+       74,   74,   74,   74,   74,   78,   78,   78,   78,   78,
+       78,  135,  120,  416,   74,  120,  120,  141,  415,  120,
+       78,  120,  192,  192,  192,  141,   74,  215,  215,  215,
+      414,   79,   78,   79,   79,   79,   79,   79,   79,   80,
+      413,   80,   80,   80,   80,   80,   80,  211,   79,  155,
+      155,  155,  155,  155,  155,  211,   80,   81,  411,   81,
+
+       79,  410,   81,   81,   81,   81,   81,   81,   80,   83,
+      381,   83,   83,   83,   83,   83,   83,  226,  226,  226,
+      409,  381,  151,  381,  151,  408,   83,  151,  151,  151,
+      151,  151,  151,  234,  234,  234,  398,  397,   83,  153,
+      153,  153,  153,  153,  153,  241,  241,  241,  396,  395,
+      154,  393,  154,  392,  153,  154,  154,  154,  154,  154,
+      154,  245,  245,  245,  391,  388,  153,  156,  156,  156,
+      156,  156,  156,  219,  219,  219,  219,  219,  219,  220,
+      220,  220,  220,  220,  220,  221,  221,  221,  221,  221,
+      221,  222,  222,  222,  222,  222,  222,  251,  251,  251,
+
+      422,  422,  422,  422,  423,  423,  424,  424,  425,  387,
+      425,  425,  385,  382,  380,  379,  378,  376,  375,  374,
+      371,  370,  369,  368,  367,  366,  365,  364,  359,  356,
+      353,  352,  351,  350,  349,  347,  345,  344,  343,  342,
+      340,  339,  337,  335,  334,  333,  332,  331,  330,  329,
+      327,  326,  325,  324,  323,  322,  321,  320,  319,  315,
+      314,  311,  300,  296,  295,  294,  293,  286,  285,  284,
+      279,  278,  277,  276,  275,  274,  271,  270,  269,  268,
+      267,  266,  265,  264,  263,  262,  261,  260,  259,  258,
+      257,  250,  249,  248,  247,  246,  244,  240,  239,  238,
+
+      237,  233,  232,  231,  230,  229,  228,  225,  223,  218,
+      217,  216,  214,  213,  212,  210,  209,  208,  207,  206,
+      205,  204,  203,  202,  201,  200,  199,  198,  197,  196,
+      195,  194,  193,  191,  190,  189,  188,  187,  186,  185,
+      184,  183,  182,  181,  180,  179,  177,  176,  175,  174,
+      173,  172,  171,  170,  169,  168,  166,  165,  164,  163,
+      162,  161,  146,  144,  143,  142,  140,  139,  138,  137,
+      136,  134,  133,  132,  131,  130,  129,  128,  127,  126,
+      125,  124,  123,  121,  118,  117,  116,  115,  114,  113,
+      112,  111,  110,  109,  108,  107,  106,  105,  104,  103,
+
+      102,  101,  100,   99,   98,   97,   96,   95,   91,   87,
+       60,   53,   48,   46,   43,   40,   27,   24,   16,   11,
+        7,  421,  421,  421,  421,  421,  421,  421,  421,  421,
+      421,  421,  421,  421,  421,  421,  421,  421,  421,  421,
+      421,  421,  421,  421,  421,  421,  421,  421,  421,  421,
+      421,  421,  421,  421,  421,  421,  421,  421,  421,  421,
+      421,  421,  421,  421,  421,  421,  421,  421,  421,  421,
+      421,  421,  421,  421,  421,  421,  421,  421,  421,  421,
+      421,  421,  421,  421,  421,  421,  421
     } ;
 
 /* Table of booleans, true if rule could match eol. */
-static yyconst flex_int32_t yy_rule_can_match_eol[146] =
+static yyconst flex_int32_t yy_rule_can_match_eol[147] =
     {   0,
 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 1, 0, 0,     };
+    0, 0, 0, 0, 1, 0, 0,     };
 
 /* The intent behind this definition is that it'll catch
  * any uses of REJECT which flex missed.
  */
 #define REJECT reject_used_but_not_detected
 #define yymore() yymore_used_but_not_detected
 #define YY_MORE_ADJ 0
 #define YY_RESTORE_YY_MORE_OFFSET
@@ -751,17 +759,17 @@ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 This file contains the Lex specification for GLSL ES.
 Based on ANSI C grammar, Lex specification:
 http://www.lysator.liu.se/c/ANSI-C-grammar-l.html
 
-IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_glslang_lexer.sh,
+IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh,
 WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp).
 */
 
 #include "compiler/glslang.h"
 #include "compiler/ParseHelper.h"
 #include "compiler/util.h"
 #include "glslang_tab.h"
 
@@ -1057,23 +1065,23 @@ yy_match:
 			if ( yy_accept[yy_current_state] )
 				{
 				yyg->yy_last_accepting_state = yy_current_state;
 				yyg->yy_last_accepting_cpos = yy_cp;
 				}
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 				{
 				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 411 )
+				if ( yy_current_state >= 422 )
 					yy_c = yy_meta[(unsigned int) yy_c];
 				}
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
 			++yy_cp;
 			}
-		while ( yy_current_state != 410 );
+		while ( yy_current_state != 421 );
 		yy_cp = yyg->yy_last_accepting_cpos;
 		yy_current_state = yyg->yy_last_accepting_state;
 
 yy_find_action:
 		yy_act = yy_accept[yy_current_state];
 
 		YY_DO_BEFORE_ACTION;
 
@@ -1280,21 +1288,21 @@ YY_RULE_SETUP
 { context->lexAfterType = true; return SAMPLER2D; }
 	YY_BREAK
 case 46:
 YY_RULE_SETUP
 { context->lexAfterType = true; return SAMPLERCUBE; }
 	YY_BREAK
 case 47:
 YY_RULE_SETUP
-{ context->lexAfterType = true; return(STRUCT); }
+{ context->lexAfterType = true; return SAMPLER_EXTERNAL_OES; }
 	YY_BREAK
 case 48:
 YY_RULE_SETUP
-{ return reserved_word(yyscanner); }
+{ context->lexAfterType = true; return(STRUCT); }
 	YY_BREAK
 case 49:
 YY_RULE_SETUP
 { return reserved_word(yyscanner); }
 	YY_BREAK
 case 50:
 YY_RULE_SETUP
 { return reserved_word(yyscanner); }
@@ -1444,256 +1452,260 @@ YY_RULE_SETUP
 { return reserved_word(yyscanner); }
 	YY_BREAK
 case 87:
 YY_RULE_SETUP
 { return reserved_word(yyscanner); }
 	YY_BREAK
 case 88:
 YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 89:
+YY_RULE_SETUP
 {
    yylval->lex.string = NewPoolTString(yytext); 
    return check_type(yyscanner);
 }
 	YY_BREAK
-case 89:
-YY_RULE_SETUP
-{ yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
-	YY_BREAK
 case 90:
 YY_RULE_SETUP
 { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
 	YY_BREAK
 case 91:
 YY_RULE_SETUP
-{ context->error(yylineno, "Invalid Octal number.", yytext, "", ""); context->recover(); return 0;}
+{ yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
 	YY_BREAK
 case 92:
 YY_RULE_SETUP
-{ yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
+{ context->error(yylineno, "Invalid Octal number.", yytext, "", ""); context->recover(); return 0;}
 	YY_BREAK
 case 93:
 YY_RULE_SETUP
-{ yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
+{ yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
 	YY_BREAK
 case 94:
 YY_RULE_SETUP
 { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
 	YY_BREAK
 case 95:
 YY_RULE_SETUP
 { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
 	YY_BREAK
 case 96:
 YY_RULE_SETUP
-{  return(ADD_ASSIGN); }
+{ yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
 	YY_BREAK
 case 97:
 YY_RULE_SETUP
-{  return(SUB_ASSIGN); }
+{  return(ADD_ASSIGN); }
 	YY_BREAK
 case 98:
 YY_RULE_SETUP
-{  return(MUL_ASSIGN); }
+{  return(SUB_ASSIGN); }
 	YY_BREAK
 case 99:
 YY_RULE_SETUP
-{  return(DIV_ASSIGN); }
+{  return(MUL_ASSIGN); }
 	YY_BREAK
 case 100:
 YY_RULE_SETUP
-{  return(MOD_ASSIGN); }
+{  return(DIV_ASSIGN); }
 	YY_BREAK
 case 101:
 YY_RULE_SETUP
-{  return(LEFT_ASSIGN); }
+{  return(MOD_ASSIGN); }
 	YY_BREAK
 case 102:
 YY_RULE_SETUP
+{  return(LEFT_ASSIGN); }
+	YY_BREAK
+case 103:
+YY_RULE_SETUP
 {  return(RIGHT_ASSIGN); }
 	YY_BREAK
-case 103:
+case 104:
 YY_RULE_SETUP
 {  return(AND_ASSIGN); }
 	YY_BREAK
-case 104:
+case 105:
 YY_RULE_SETUP
 {  return(XOR_ASSIGN); }
 	YY_BREAK
-case 105:
+case 106:
 YY_RULE_SETUP
 {  return(OR_ASSIGN); }
 	YY_BREAK
-case 106:
-YY_RULE_SETUP
-{  return(INC_OP); }
-	YY_BREAK
 case 107:
 YY_RULE_SETUP
-{  return(DEC_OP); }
+{  return(INC_OP); }
 	YY_BREAK
 case 108:
 YY_RULE_SETUP
+{  return(DEC_OP); }
+	YY_BREAK
+case 109:
+YY_RULE_SETUP
 {  return(AND_OP); }
 	YY_BREAK
-case 109:
+case 110:
 YY_RULE_SETUP
 {  return(OR_OP); }
 	YY_BREAK
-case 110:
+case 111:
 YY_RULE_SETUP
 {  return(XOR_OP); }
 	YY_BREAK
-case 111:
+case 112:
 YY_RULE_SETUP
 {  return(LE_OP); }
 	YY_BREAK
-case 112:
+case 113:
 YY_RULE_SETUP
 {  return(GE_OP); }
 	YY_BREAK
-case 113:
+case 114:
 YY_RULE_SETUP
 {  return(EQ_OP); }
 	YY_BREAK
-case 114:
-YY_RULE_SETUP
-{  return(NE_OP); }
-	YY_BREAK
 case 115:
 YY_RULE_SETUP
+{  return(NE_OP); }
+	YY_BREAK
+case 116:
+YY_RULE_SETUP
 {  return(LEFT_OP); }
 	YY_BREAK
-case 116:
+case 117:
 YY_RULE_SETUP
 {  return(RIGHT_OP); }
 	YY_BREAK
-case 117:
+case 118:
 YY_RULE_SETUP
 { context->lexAfterType = false; return(SEMICOLON); }
 	YY_BREAK
-case 118:
+case 119:
 YY_RULE_SETUP
 { context->lexAfterType = false; return(LEFT_BRACE); }
 	YY_BREAK
-case 119:
+case 120:
 YY_RULE_SETUP
 { return(RIGHT_BRACE); }
 	YY_BREAK
-case 120:
+case 121:
 YY_RULE_SETUP
 { if (context->inTypeParen) context->lexAfterType = false; return(COMMA); }
 	YY_BREAK
-case 121:
+case 122:
 YY_RULE_SETUP
 { return(COLON); }
 	YY_BREAK
-case 122:
+case 123:
 YY_RULE_SETUP
 { context->lexAfterType = false; return(EQUAL); }
 	YY_BREAK
-case 123:
+case 124:
 YY_RULE_SETUP
 { context->lexAfterType = false; context->inTypeParen = true; return(LEFT_PAREN); }
 	YY_BREAK
-case 124:
+case 125:
 YY_RULE_SETUP
 { context->inTypeParen = false; return(RIGHT_PAREN); }
 	YY_BREAK
-case 125:
-YY_RULE_SETUP
-{ return(LEFT_BRACKET); }
-	YY_BREAK
 case 126:
 YY_RULE_SETUP
+{ return(LEFT_BRACKET); }
+	YY_BREAK
+case 127:
+YY_RULE_SETUP
 { return(RIGHT_BRACKET); }
 	YY_BREAK
-case 127:
+case 128:
 YY_RULE_SETUP
 { BEGIN(FIELDS);  return(DOT); }
 	YY_BREAK
-case 128:
+case 129:
 YY_RULE_SETUP
 { return(BANG); }
 	YY_BREAK
-case 129:
+case 130:
 YY_RULE_SETUP
 { return(DASH); }
 	YY_BREAK
-case 130:
+case 131:
 YY_RULE_SETUP
 { return(TILDE); }
 	YY_BREAK
-case 131:
-YY_RULE_SETUP
-{ return(PLUS); }
-	YY_BREAK
 case 132:
 YY_RULE_SETUP
-{ return(STAR); }
+{ return(PLUS); }
 	YY_BREAK
 case 133:
 YY_RULE_SETUP
-{ return(SLASH); }
+{ return(STAR); }
 	YY_BREAK
 case 134:
 YY_RULE_SETUP
-{ return(PERCENT); }
+{ return(SLASH); }
 	YY_BREAK
 case 135:
 YY_RULE_SETUP
-{ return(LEFT_ANGLE); }
+{ return(PERCENT); }
 	YY_BREAK
 case 136:
 YY_RULE_SETUP
-{ return(RIGHT_ANGLE); }
+{ return(LEFT_ANGLE); }
 	YY_BREAK
 case 137:
 YY_RULE_SETUP
-{ return(VERTICAL_BAR); }
+{ return(RIGHT_ANGLE); }
 	YY_BREAK
 case 138:
 YY_RULE_SETUP
+{ return(VERTICAL_BAR); }
+	YY_BREAK
+case 139:
+YY_RULE_SETUP
 { return(CARET); }
 	YY_BREAK
-case 139:
+case 140:
 YY_RULE_SETUP
 { return(AMPERSAND); }
 	YY_BREAK
-case 140:
+case 141:
 YY_RULE_SETUP
 { return(QUESTION); }
 	YY_BREAK
-case 141:
+case 142:
 YY_RULE_SETUP
 { 
     BEGIN(INITIAL);
     yylval->lex.string = NewPoolTString(yytext); 
     return FIELD_SELECTION;
 }
 	YY_BREAK
-case 142:
+case 143:
 YY_RULE_SETUP
 {}
 	YY_BREAK
-case 143:
-/* rule 143 can match eol */
+case 144:
+/* rule 144 can match eol */
 YY_RULE_SETUP
 {  }
 	YY_BREAK
 case YY_STATE_EOF(INITIAL):
 case YY_STATE_EOF(COMMENT):
 case YY_STATE_EOF(FIELDS):
 { context->AfterEOF = true; yyterminate(); }
 	YY_BREAK
-case 144:
+case 145:
 YY_RULE_SETUP
 { context->warning(yylineno, "Unknown char", yytext, ""); return 0; }
 	YY_BREAK
-case 145:
+case 146:
 YY_RULE_SETUP
 ECHO;
 	YY_BREAK
 
 	case YY_END_OF_BUFFER:
 		{
 		/* Amount of text matched not including the EOB char. */
 		int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1;
@@ -1979,17 +1991,17 @@ static int yy_get_next_buffer (yyscan_t 
 		if ( yy_accept[yy_current_state] )
 			{
 			yyg->yy_last_accepting_state = yy_current_state;
 			yyg->yy_last_accepting_cpos = yy_cp;
 			}
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			{
 			yy_current_state = (int) yy_def[yy_current_state];
-			if ( yy_current_state >= 411 )
+			if ( yy_current_state >= 422 )
 				yy_c = yy_meta[(unsigned int) yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
 		}
 
 	return yy_current_state;
 }
 
@@ -2008,21 +2020,21 @@ static int yy_get_next_buffer (yyscan_t 
 	if ( yy_accept[yy_current_state] )
 		{
 		yyg->yy_last_accepting_state = yy_current_state;
 		yyg->yy_last_accepting_cpos = yy_cp;
 		}
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		{
 		yy_current_state = (int) yy_def[yy_current_state];
-		if ( yy_current_state >= 411 )
+		if ( yy_current_state >= 422 )
 			yy_c = yy_meta[(unsigned int) yy_c];
 		}
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-	yy_is_jam = (yy_current_state == 410);
+	yy_is_jam = (yy_current_state == 421);
 
 	return yy_is_jam ? 0 : yy_current_state;
 }
 
 #ifndef YY_NO_INPUT
 #ifdef __cplusplus
     static int yyinput (yyscan_t yyscanner)
 #else
--- a/gfx/angle/src/compiler/glslang_tab.cpp
+++ b/gfx/angle/src/compiler/glslang_tab.cpp
@@ -101,67 +101,68 @@
      INOUT_QUAL = 290,
      UNIFORM = 291,
      VARYING = 292,
      STRUCT = 293,
      VOID_TYPE = 294,
      WHILE = 295,
      SAMPLER2D = 296,
      SAMPLERCUBE = 297,
-     IDENTIFIER = 298,
-     TYPE_NAME = 299,
-     FLOATCONSTANT = 300,
-     INTCONSTANT = 301,
-     BOOLCONSTANT = 302,
-     FIELD_SELECTION = 303,
-     LEFT_OP = 304,
-     RIGHT_OP = 305,
-     INC_OP = 306,
-     DEC_OP = 307,
-     LE_OP = 308,
-     GE_OP = 309,
-     EQ_OP = 310,
-     NE_OP = 311,
-     AND_OP = 312,
-     OR_OP = 313,
-     XOR_OP = 314,
-     MUL_ASSIGN = 315,
-     DIV_ASSIGN = 316,
-     ADD_ASSIGN = 317,
-     MOD_ASSIGN = 318,
-     LEFT_ASSIGN = 319,
-     RIGHT_ASSIGN = 320,
-     AND_ASSIGN = 321,
-     XOR_ASSIGN = 322,
-     OR_ASSIGN = 323,
-     SUB_ASSIGN = 324,
-     LEFT_PAREN = 325,
-     RIGHT_PAREN = 326,
-     LEFT_BRACKET = 327,
-     RIGHT_BRACKET = 328,
-     LEFT_BRACE = 329,
-     RIGHT_BRACE = 330,
-     DOT = 331,
-     COMMA = 332,
-     COLON = 333,
-     EQUAL = 334,
-     SEMICOLON = 335,
-     BANG = 336,
-     DASH = 337,
-     TILDE = 338,
-     PLUS = 339,
-     STAR = 340,
-     SLASH = 341,
-     PERCENT = 342,
-     LEFT_ANGLE = 343,
-     RIGHT_ANGLE = 344,
-     VERTICAL_BAR = 345,
-     CARET = 346,
-     AMPERSAND = 347,
-     QUESTION = 348
+     SAMPLER_EXTERNAL_OES = 298,
+     IDENTIFIER = 299,
+     TYPE_NAME = 300,
+     FLOATCONSTANT = 301,
+     INTCONSTANT = 302,
+     BOOLCONSTANT = 303,
+     FIELD_SELECTION = 304,
+     LEFT_OP = 305,
+     RIGHT_OP = 306,
+     INC_OP = 307,
+     DEC_OP = 308,
+     LE_OP = 309,
+     GE_OP = 310,
+     EQ_OP = 311,
+     NE_OP = 312,
+     AND_OP = 313,
+     OR_OP = 314,
+     XOR_OP = 315,
+     MUL_ASSIGN = 316,
+     DIV_ASSIGN = 317,
+     ADD_ASSIGN = 318,
+     MOD_ASSIGN = 319,
+     LEFT_ASSIGN = 320,
+     RIGHT_ASSIGN = 321,
+     AND_ASSIGN = 322,
+     XOR_ASSIGN = 323,
+     OR_ASSIGN = 324,
+     SUB_ASSIGN = 325,
+     LEFT_PAREN = 326,
+     RIGHT_PAREN = 327,
+     LEFT_BRACKET = 328,
+     RIGHT_BRACKET = 329,
+     LEFT_BRACE = 330,
+     RIGHT_BRACE = 331,
+     DOT = 332,
+     COMMA = 333,
+     COLON = 334,
+     EQUAL = 335,
+     SEMICOLON = 336,
+     BANG = 337,
+     DASH = 338,
+     TILDE = 339,
+     PLUS = 340,
+     STAR = 341,
+     SLASH = 342,
+     PERCENT = 343,
+     LEFT_ANGLE = 344,
+     RIGHT_ANGLE = 345,
+     VERTICAL_BAR = 346,
+     CARET = 347,
+     AMPERSAND = 348,
+     QUESTION = 349
    };
 #endif
 /* Tokens.  */
 #define INVARIANT 258
 #define HIGH_PRECISION 259
 #define MEDIUM_PRECISION 260
 #define LOW_PRECISION 261
 #define PRECISION 262
@@ -195,81 +196,82 @@
 #define INOUT_QUAL 290
 #define UNIFORM 291
 #define VARYING 292
 #define STRUCT 293
 #define VOID_TYPE 294
 #define WHILE 295
 #define SAMPLER2D 296
 #define SAMPLERCUBE 297
-#define IDENTIFIER 298
-#define TYPE_NAME 299
-#define FLOATCONSTANT 300
-#define INTCONSTANT 301
-#define BOOLCONSTANT 302
-#define FIELD_SELECTION 303
-#define LEFT_OP 304
-#define RIGHT_OP 305
-#define INC_OP 306
-#define DEC_OP 307
-#define LE_OP 308
-#define GE_OP 309
-#define EQ_OP 310
-#define NE_OP 311
-#define AND_OP 312
-#define OR_OP 313
-#define XOR_OP 314
-#define MUL_ASSIGN 315
-#define DIV_ASSIGN 316
-#define ADD_ASSIGN 317
-#define MOD_ASSIGN 318
-#define LEFT_ASSIGN 319
-#define RIGHT_ASSIGN 320
-#define AND_ASSIGN 321
-#define XOR_ASSIGN 322
-#define OR_ASSIGN 323
-#define SUB_ASSIGN 324
-#define LEFT_PAREN 325
-#define RIGHT_PAREN 326
-#define LEFT_BRACKET 327
-#define RIGHT_BRACKET 328
-#define LEFT_BRACE 329
-#define RIGHT_BRACE 330
-#define DOT 331
-#define COMMA 332
-#define COLON 333
-#define EQUAL 334
-#define SEMICOLON 335
-#define BANG 336
-#define DASH 337
-#define TILDE 338
-#define PLUS 339
-#define STAR 340
-#define SLASH 341
-#define PERCENT 342
-#define LEFT_ANGLE 343
-#define RIGHT_ANGLE 344
-#define VERTICAL_BAR 345
-#define CARET 346
-#define AMPERSAND 347
-#define QUESTION 348
+#define SAMPLER_EXTERNAL_OES 298
+#define IDENTIFIER 299
+#define TYPE_NAME 300
+#define FLOATCONSTANT 301
+#define INTCONSTANT 302
+#define BOOLCONSTANT 303
+#define FIELD_SELECTION 304
+#define LEFT_OP 305
+#define RIGHT_OP 306
+#define INC_OP 307
+#define DEC_OP 308
+#define LE_OP 309
+#define GE_OP 310
+#define EQ_OP 311
+#define NE_OP 312
+#define AND_OP 313
+#define OR_OP 314
+#define XOR_OP 315
+#define MUL_ASSIGN 316
+#define DIV_ASSIGN 317
+#define ADD_ASSIGN 318
+#define MOD_ASSIGN 319
+#define LEFT_ASSIGN 320
+#define RIGHT_ASSIGN 321
+#define AND_ASSIGN 322
+#define XOR_ASSIGN 323
+#define OR_ASSIGN 324
+#define SUB_ASSIGN 325
+#define LEFT_PAREN 326
+#define RIGHT_PAREN 327
+#define LEFT_BRACKET 328
+#define RIGHT_BRACKET 329
+#define LEFT_BRACE 330
+#define RIGHT_BRACE 331
+#define DOT 332
+#define COMMA 333
+#define COLON 334
+#define EQUAL 335
+#define SEMICOLON 336
+#define BANG 337
+#define DASH 338
+#define TILDE 339
+#define PLUS 340
+#define STAR 341
+#define SLASH 342
+#define PERCENT 343
+#define LEFT_ANGLE 344
+#define RIGHT_ANGLE 345
+#define VERTICAL_BAR 346
+#define CARET 347
+#define AMPERSAND 348
+#define QUESTION 349
 
 
 
 
 /* Copy the first part of user declarations.  */
 
 
 //
 // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
-// This file is auto-generated by generate_glslang_parser.sh. DO NOT EDIT!
+// This file is auto-generated by generate_parser.sh. DO NOT EDIT!
 
 #include "compiler/SymbolTable.h"
 #include "compiler/ParseHelper.h"
 #include "GLSLANG/ShaderLang.h"
 
 #define YYLEX_PARAM context->scanner
 
 
@@ -320,17 +322,17 @@ typedef union YYSTYPE
             TQualifier qualifier;
             TFunction* function;
             TParameter param;
             TTypeLine typeLine;
             TTypeList* typeList;
         };
     } interm;
 }
-/* Line 193 of yacc.c.  */
+/* Line 187 of yacc.c.  */
 
 	YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
 #endif
 
 
@@ -410,17 +412,17 @@ typedef short int yytype_int16;
 # else
 #  define YYSIZE_T unsigned int
 # endif
 #endif
 
 #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
 
 #ifndef YY_
-# if defined YYENABLE_NLS && YYENABLE_NLS
+# if YYENABLE_NLS
 #  if ENABLE_NLS
 #   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
 #   define YY_(msgid) dgettext ("bison-runtime", msgid)
 #  endif
 # endif
 # ifndef YY_
 #  define YY_(msgid) msgid
 # endif
@@ -573,32 +575,32 @@ union yyalloc
 	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
 	yyptr += yynewbytes / sizeof (*yyptr);				\
       }									\
     while (YYID (0))
 
 #endif
 
 /* YYFINAL -- State number of the termination state.  */
-#define YYFINAL  69
+#define YYFINAL  70
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   1334
+#define YYLAST   1381
 
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  94
+#define YYNTOKENS  95
 /* YYNNTS -- Number of nonterminals.  */
 #define YYNNTS  78
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  193
+#define YYNRULES  194
 /* YYNRULES -- Number of states.  */
-#define YYNSTATES  296
+#define YYNSTATES  297
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   348
+#define YYMAXUTOK   349
 
 #define YYTRANSLATE(YYX)						\
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
 
 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
 static const yytype_uint8 yytranslate[] =
 {
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -630,17 +632,17 @@ static const yytype_uint8 yytranslate[] 
        5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
       15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
       25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
       35,    36,    37,    38,    39,    40,    41,    42,    43,    44,
       45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
       55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
       65,    66,    67,    68,    69,    70,    71,    72,    73,    74,
       75,    76,    77,    78,    79,    80,    81,    82,    83,    84,
-      85,    86,    87,    88,    89,    90,    91,    92,    93
+      85,    86,    87,    88,    89,    90,    91,    92,    93,    94
 };
 
 #if YYDEBUG
 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
    YYRHS.  */
 static const yytype_uint16 yyprhs[] =
 {
        0,     0,     3,     5,     7,     9,    11,    13,    17,    19,
@@ -651,130 +653,130 @@ static const yytype_uint16 yyprhs[] =
      140,   142,   144,   146,   148,   152,   154,   158,   160,   164,
      166,   172,   174,   178,   180,   182,   184,   186,   188,   190,
      194,   196,   199,   202,   207,   210,   212,   214,   217,   221,
      225,   228,   234,   238,   241,   245,   248,   249,   251,   253,
      255,   257,   259,   263,   269,   276,   282,   284,   287,   292,
      298,   303,   306,   308,   311,   313,   315,   317,   320,   322,
      324,   327,   329,   331,   333,   335,   340,   342,   344,   346,
      348,   350,   352,   354,   356,   358,   360,   362,   364,   366,
-     368,   370,   372,   374,   376,   378,   380,   386,   391,   393,
-     396,   400,   402,   406,   408,   413,   415,   417,   419,   421,
-     423,   425,   427,   429,   431,   434,   435,   436,   442,   444,
-     446,   449,   453,   455,   458,   460,   463,   469,   473,   475,
-     477,   482,   483,   490,   491,   500,   501,   509,   511,   513,
-     515,   516,   519,   523,   526,   529,   532,   536,   539,   541,
-     544,   546,   548,   549
+     368,   370,   372,   374,   376,   378,   380,   382,   388,   393,
+     395,   398,   402,   404,   408,   410,   415,   417,   419,   421,
+     423,   425,   427,   429,   431,   433,   436,   437,   438,   444,
+     446,   448,   451,   455,   457,   460,   462,   465,   471,   475,
+     477,   479,   484,   485,   492,   493,   502,   503,   511,   513,
+     515,   517,   518,   521,   525,   528,   531,   534,   538,   541,
+     543,   546,   548,   550,   551
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
 static const yytype_int16 yyrhs[] =
 {
-     168,     0,    -1,    43,    -1,    95,    -1,    46,    -1,    45,
-      -1,    47,    -1,    70,   122,    71,    -1,    96,    -1,    97,
-      72,    98,    73,    -1,    99,    -1,    97,    76,    48,    -1,
-      97,    51,    -1,    97,    52,    -1,   122,    -1,   100,    -1,
-     101,    -1,    97,    76,   101,    -1,   103,    71,    -1,   102,
-      71,    -1,   104,    39,    -1,   104,    -1,   104,   120,    -1,
-     103,    77,   120,    -1,   105,    70,    -1,   137,    -1,    43,
-      -1,    48,    -1,    97,    -1,    51,   106,    -1,    52,   106,
-      -1,   107,   106,    -1,    84,    -1,    82,    -1,    81,    -1,
-     106,    -1,   108,    85,   106,    -1,   108,    86,   106,    -1,
-     108,    -1,   109,    84,   108,    -1,   109,    82,   108,    -1,
-     109,    -1,   110,    -1,   111,    88,   110,    -1,   111,    89,
-     110,    -1,   111,    53,   110,    -1,   111,    54,   110,    -1,
-     111,    -1,   112,    55,   111,    -1,   112,    56,   111,    -1,
-     112,    -1,   113,    -1,   114,    -1,   115,    -1,   116,    57,
-     115,    -1,   116,    -1,   117,    59,   116,    -1,   117,    -1,
-     118,    58,   117,    -1,   118,    -1,   118,    93,   122,    78,
-     120,    -1,   119,    -1,   106,   121,   120,    -1,    79,    -1,
-      60,    -1,    61,    -1,    62,    -1,    69,    -1,   120,    -1,
-     122,    77,   120,    -1,   119,    -1,   125,    80,    -1,   133,
-      80,    -1,     7,   138,   139,    80,    -1,   126,    71,    -1,
-     128,    -1,   127,    -1,   128,   130,    -1,   127,    77,   130,
-      -1,   135,    43,    70,    -1,   137,    43,    -1,   137,    43,
-      72,   123,    73,    -1,   136,   131,   129,    -1,   131,   129,
-      -1,   136,   131,   132,    -1,   131,   132,    -1,    -1,    33,
-      -1,    34,    -1,    35,    -1,   137,    -1,   134,    -1,   133,
-      77,    43,    -1,   133,    77,    43,    72,    73,    -1,   133,
-      77,    43,    72,   123,    73,    -1,   133,    77,    43,    79,
-     146,    -1,   135,    -1,   135,    43,    -1,   135,    43,    72,
-      73,    -1,   135,    43,    72,   123,    73,    -1,   135,    43,
-      79,   146,    -1,     3,    43,    -1,   137,    -1,   136,   137,
+     169,     0,    -1,    44,    -1,    96,    -1,    47,    -1,    46,
+      -1,    48,    -1,    71,   123,    72,    -1,    97,    -1,    98,
+      73,    99,    74,    -1,   100,    -1,    98,    77,    49,    -1,
+      98,    52,    -1,    98,    53,    -1,   123,    -1,   101,    -1,
+     102,    -1,    98,    77,   102,    -1,   104,    72,    -1,   103,
+      72,    -1,   105,    39,    -1,   105,    -1,   105,   121,    -1,
+     104,    78,   121,    -1,   106,    71,    -1,   141,    -1,    44,
+      -1,    49,    -1,    98,    -1,    52,   107,    -1,    53,   107,
+      -1,   108,   107,    -1,    85,    -1,    83,    -1,    82,    -1,
+     107,    -1,   109,    86,   107,    -1,   109,    87,   107,    -1,
+     109,    -1,   110,    85,   109,    -1,   110,    83,   109,    -1,
+     110,    -1,   111,    -1,   112,    89,   111,    -1,   112,    90,
+     111,    -1,   112,    54,   111,    -1,   112,    55,   111,    -1,
+     112,    -1,   113,    56,   112,    -1,   113,    57,   112,    -1,
+     113,    -1,   114,    -1,   115,    -1,   116,    -1,   117,    58,
+     116,    -1,   117,    -1,   118,    60,   117,    -1,   118,    -1,
+     119,    59,   118,    -1,   119,    -1,   119,    94,   123,    79,
+     121,    -1,   120,    -1,   107,   122,   121,    -1,    80,    -1,
+      61,    -1,    62,    -1,    63,    -1,    70,    -1,   121,    -1,
+     123,    78,   121,    -1,   120,    -1,   126,    81,    -1,   134,
+      81,    -1,     7,   139,   140,    81,    -1,   127,    72,    -1,
+     129,    -1,   128,    -1,   129,   131,    -1,   128,    78,   131,
+      -1,   136,    44,    71,    -1,   138,    44,    -1,   138,    44,
+      73,   124,    74,    -1,   137,   132,   130,    -1,   132,   130,
+      -1,   137,   132,   133,    -1,   132,   133,    -1,    -1,    33,
+      -1,    34,    -1,    35,    -1,   138,    -1,   135,    -1,   134,
+      78,    44,    -1,   134,    78,    44,    73,    74,    -1,   134,
+      78,    44,    73,   124,    74,    -1,   134,    78,    44,    80,
+     147,    -1,   136,    -1,   136,    44,    -1,   136,    44,    73,
+      74,    -1,   136,    44,    73,   124,    74,    -1,   136,    44,
+      80,   147,    -1,     3,    44,    -1,   138,    -1,   137,   138,
       -1,     9,    -1,     8,    -1,    37,    -1,     3,    37,    -1,
-      36,    -1,   139,    -1,   138,   139,    -1,     4,    -1,     5,
-      -1,     6,    -1,   140,    -1,   140,    72,   123,    73,    -1,
+      36,    -1,   140,    -1,   139,   140,    -1,     4,    -1,     5,
+      -1,     6,    -1,   141,    -1,   141,    73,   124,    74,    -1,
       39,    -1,    11,    -1,    12,    -1,    10,    -1,    27,    -1,
       28,    -1,    29,    -1,    21,    -1,    22,    -1,    23,    -1,
       24,    -1,    25,    -1,    26,    -1,    30,    -1,    31,    -1,
-      32,    -1,    41,    -1,    42,    -1,   141,    -1,    44,    -1,
-      38,    43,    74,   142,    75,    -1,    38,    74,   142,    75,
-      -1,   143,    -1,   142,   143,    -1,   137,   144,    80,    -1,
-     145,    -1,   144,    77,   145,    -1,    43,    -1,    43,    72,
-     123,    73,    -1,   120,    -1,   124,    -1,   150,    -1,   149,
-      -1,   147,    -1,   156,    -1,   157,    -1,   160,    -1,   167,
-      -1,    74,    75,    -1,    -1,    -1,    74,   151,   155,   152,
-      75,    -1,   154,    -1,   149,    -1,    74,    75,    -1,    74,
-     155,    75,    -1,   148,    -1,   155,   148,    -1,    80,    -1,
-     122,    80,    -1,    18,    70,   122,    71,   158,    -1,   148,
-      16,   148,    -1,   148,    -1,   122,    -1,   135,    43,    79,
-     146,    -1,    -1,    40,    70,   161,   159,    71,   153,    -1,
-      -1,    15,   162,   148,    40,    70,   122,    71,    80,    -1,
-      -1,    17,    70,   163,   164,   166,    71,   153,    -1,   156,
-      -1,   147,    -1,   159,    -1,    -1,   165,    80,    -1,   165,
-      80,   122,    -1,    14,    80,    -1,    13,    80,    -1,    20,
-      80,    -1,    20,   122,    80,    -1,    19,    80,    -1,   169,
-      -1,   168,   169,    -1,   170,    -1,   124,    -1,    -1,   125,
-     171,   154,    -1
+      32,    -1,    41,    -1,    42,    -1,    43,    -1,   142,    -1,
+      45,    -1,    38,    44,    75,   143,    76,    -1,    38,    75,
+     143,    76,    -1,   144,    -1,   143,   144,    -1,   138,   145,
+      81,    -1,   146,    -1,   145,    78,   146,    -1,    44,    -1,
+      44,    73,   124,    74,    -1,   121,    -1,   125,    -1,   151,
+      -1,   150,    -1,   148,    -1,   157,    -1,   158,    -1,   161,
+      -1,   168,    -1,    75,    76,    -1,    -1,    -1,    75,   152,
+     156,   153,    76,    -1,   155,    -1,   150,    -1,    75,    76,
+      -1,    75,   156,    76,    -1,   149,    -1,   156,   149,    -1,
+      81,    -1,   123,    81,    -1,    18,    71,   123,    72,   159,
+      -1,   149,    16,   149,    -1,   149,    -1,   123,    -1,   136,
+      44,    80,   147,    -1,    -1,    40,    71,   162,   160,    72,
+     154,    -1,    -1,    15,   163,   149,    40,    71,   123,    72,
+      81,    -1,    -1,    17,    71,   164,   165,   167,    72,   154,
+      -1,   157,    -1,   148,    -1,   160,    -1,    -1,   166,    81,
+      -1,   166,    81,   123,    -1,    14,    81,    -1,    13,    81,
+      -1,    20,    81,    -1,    20,   123,    81,    -1,    19,    81,
+      -1,   170,    -1,   169,   170,    -1,   171,    -1,   125,    -1,
+      -1,   126,   172,   155,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
        0,   153,   153,   188,   191,   204,   209,   214,   220,   223,
      296,   299,   408,   418,   431,   439,   538,   541,   549,   553,
-     560,   564,   571,   577,   586,   594,   656,   663,   673,   676,
-     686,   696,   717,   718,   719,   724,   725,   734,   746,   747,
-     755,   766,   770,   771,   781,   791,   801,   814,   815,   825,
-     838,   842,   846,   850,   851,   864,   865,   878,   879,   892,
-     893,   910,   911,   924,   925,   926,   927,   928,   932,   935,
-     946,   954,   979,   984,   991,  1027,  1030,  1037,  1045,  1066,
-    1085,  1096,  1125,  1130,  1140,  1145,  1155,  1158,  1161,  1164,
-    1170,  1177,  1187,  1203,  1221,  1245,  1268,  1272,  1290,  1298,
-    1330,  1350,  1426,  1435,  1458,  1461,  1467,  1475,  1483,  1491,
-    1494,  1501,  1504,  1507,  1513,  1516,  1531,  1535,  1539,  1543,
-    1552,  1557,  1562,  1567,  1572,  1577,  1582,  1587,  1592,  1597,
-    1603,  1609,  1615,  1620,  1625,  1630,  1643,  1656,  1664,  1667,
-    1682,  1713,  1717,  1723,  1731,  1747,  1751,  1755,  1756,  1762,
-    1763,  1764,  1765,  1766,  1770,  1771,  1771,  1771,  1781,  1782,
-    1787,  1790,  1800,  1803,  1809,  1810,  1814,  1822,  1826,  1836,
-    1841,  1858,  1858,  1863,  1863,  1870,  1870,  1878,  1881,  1887,
-    1890,  1896,  1900,  1907,  1914,  1921,  1928,  1939,  1948,  1952,
-    1959,  1962,  1968,  1968
+     560,   564,   571,   577,   586,   594,   649,   656,   666,   669,
+     679,   689,   710,   711,   712,   717,   718,   727,   739,   740,
+     748,   759,   763,   764,   774,   784,   794,   807,   808,   818,
+     831,   835,   839,   843,   844,   857,   858,   871,   872,   885,
+     886,   903,   904,   917,   918,   919,   920,   921,   925,   928,
+     939,   947,   972,   977,   984,  1020,  1023,  1030,  1038,  1059,
+    1078,  1089,  1118,  1123,  1133,  1138,  1148,  1151,  1154,  1157,
+    1163,  1170,  1173,  1189,  1207,  1231,  1254,  1258,  1276,  1284,
+    1316,  1336,  1412,  1421,  1444,  1447,  1453,  1461,  1469,  1477,
+    1487,  1494,  1497,  1500,  1506,  1509,  1524,  1528,  1532,  1536,
+    1545,  1550,  1555,  1560,  1565,  1570,  1575,  1580,  1585,  1590,
+    1596,  1602,  1608,  1613,  1618,  1627,  1632,  1645,  1658,  1666,
+    1669,  1684,  1716,  1720,  1726,  1734,  1750,  1754,  1758,  1759,
+    1765,  1766,  1767,  1768,  1769,  1773,  1774,  1774,  1774,  1784,
+    1785,  1790,  1793,  1803,  1806,  1812,  1813,  1817,  1825,  1829,
+    1839,  1844,  1861,  1861,  1866,  1866,  1873,  1873,  1881,  1884,
+    1890,  1893,  1899,  1903,  1910,  1917,  1924,  1931,  1942,  1951,
+    1955,  1962,  1965,  1971,  1971
 };
 #endif
 
 #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
    First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
 static const char *const yytname[] =
 {
   "$end", "error", "$undefined", "INVARIANT", "HIGH_PRECISION",
   "MEDIUM_PRECISION", "LOW_PRECISION", "PRECISION", "ATTRIBUTE",
   "CONST_QUAL", "BOOL_TYPE", "FLOAT_TYPE", "INT_TYPE", "BREAK", "CONTINUE",
   "DO", "ELSE", "FOR", "IF", "DISCARD", "RETURN", "BVEC2", "BVEC3",
   "BVEC4", "IVEC2", "IVEC3", "IVEC4", "VEC2", "VEC3", "VEC4", "MATRIX2",
   "MATRIX3", "MATRIX4", "IN_QUAL", "OUT_QUAL", "INOUT_QUAL", "UNIFORM",
   "VARYING", "STRUCT", "VOID_TYPE", "WHILE", "SAMPLER2D", "SAMPLERCUBE",
-  "IDENTIFIER", "TYPE_NAME", "FLOATCONSTANT", "INTCONSTANT",
-  "BOOLCONSTANT", "FIELD_SELECTION", "LEFT_OP", "RIGHT_OP", "INC_OP",
-  "DEC_OP", "LE_OP", "GE_OP", "EQ_OP", "NE_OP", "AND_OP", "OR_OP",
-  "XOR_OP", "MUL_ASSIGN", "DIV_ASSIGN", "ADD_ASSIGN", "MOD_ASSIGN",
-  "LEFT_ASSIGN", "RIGHT_ASSIGN", "AND_ASSIGN", "XOR_ASSIGN", "OR_ASSIGN",
-  "SUB_ASSIGN", "LEFT_PAREN", "RIGHT_PAREN", "LEFT_BRACKET",
+  "SAMPLER_EXTERNAL_OES", "IDENTIFIER", "TYPE_NAME", "FLOATCONSTANT",
+  "INTCONSTANT", "BOOLCONSTANT", "FIELD_SELECTION", "LEFT_OP", "RIGHT_OP",
+  "INC_OP", "DEC_OP", "LE_OP", "GE_OP", "EQ_OP", "NE_OP", "AND_OP",
+  "OR_OP", "XOR_OP", "MUL_ASSIGN", "DIV_ASSIGN", "ADD_ASSIGN",