merge m-c to devtools
authorRob Campbell <rcampbell@mozilla.com>
Tue, 24 May 2011 14:04:56 -0300
changeset 70886 2ee9b3a8c7c9
parent 70885 c4bd2219aafc (current diff)
parent 70107 9eae975b3d6f (diff)
child 70887 6d63840e3a49
push id20437
push userdcamp@campd.org
push date2011-06-10 22:40 +0000
treeherdermozilla-central@6da2c7c5c170 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone6.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 m-c to devtools
gfx/angle/angle-fixes.patch
gfx/angle/angle-pbuffers.patch
--- a/accessible/src/base/nsARIAMap.cpp
+++ b/accessible/src/base/nsARIAMap.cpp
@@ -472,17 +472,18 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] 
   },
   {
     "tab",
     nsIAccessibleRole::ROLE_PAGETAB,
     kUseMapRole,
     eNoValue,
     eSwitchAction,
     eNoLiveAttr,
-    kNoReqStates
+    kNoReqStates,
+    eARIASelectable
   },
   {
     "tablist",
     nsIAccessibleRole::ROLE_PAGETABLIST,
     kUseMapRole,
     eNoValue,
     eNoAction,
     ePoliteLiveAttr,
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -1528,25 +1528,30 @@ nsAccessible::GetState(PRUint32* aState,
 
 PRUint64
 nsAccessible::State()
 {
   if (IsDefunct())
     return states::DEFUNCT;
 
   PRUint64 state = NativeState();
-  // Apply ARIA states to be sure accessible states will be overriden.
+  // Apply ARIA states to be sure accessible states will be overridden.
   ApplyARIAState(&state);
 
-  if (mRoleMapEntry && mRoleMapEntry->role == nsIAccessibleRole::ROLE_PAGETAB) {
+  if (mRoleMapEntry && mRoleMapEntry->role == nsIAccessibleRole::ROLE_PAGETAB &&
+      !(state & states::SELECTED) &&
+      !mContent->AttrValueIs(kNameSpaceID_None,
+                             nsAccessibilityAtoms::aria_selected,
+                             nsAccessibilityAtoms::_false, eCaseMatters)) {
+    // Special case: for tabs, focused implies selected, unless explicitly
+    // false, i.e. aria-selected="false".
     if (state & states::FOCUSED) {
       state |= states::SELECTED;
     } else {
-      // Expose 'selected' state on ARIA tab if the focus is on internal element
-      // of related tabpanel.
+      // If focus is in a child of the tab panel surely the tab is selected!
       nsCOMPtr<nsIAccessible> tabPanel = nsRelUtils::
         GetRelatedAccessible(this, nsIAccessibleRelation::RELATION_LABEL_FOR);
 
       if (nsAccUtils::Role(tabPanel) == nsIAccessibleRole::ROLE_PROPERTYPAGE) {
         nsRefPtr<nsAccessible> tabPanelAcc(do_QueryObject(tabPanel));
         nsINode *tabPanelNode = tabPanelAcc->GetNode();
         if (nsCoreUtils::IsAncestorOf(tabPanelNode, gLastFocusedNode))
           state |= states::SELECTED;
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -1032,16 +1032,24 @@ nsDocAccessible::AttributeChangedImpl(ns
       aAttribute == nsAccessibilityAtoms::title ||
       aAttribute == nsAccessibilityAtoms::aria_label ||
       aAttribute == nsAccessibilityAtoms::aria_labelledby) {
     FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE,
                                aContent);
     return;
   }
 
+  if (aAttribute == nsAccessibilityAtoms::aria_busy) {
+    PRBool isOn = !aContent->AttrValueIs(aNameSpaceID, aAttribute,
+                                         nsAccessibilityAtoms::_true, eCaseMatters);
+    nsRefPtr<AccEvent> event = new AccStateChangeEvent(aContent, states::BUSY, isOn);
+    FireDelayedAccessibleEvent(event);
+    return;
+  }
+
   if (aAttribute == nsAccessibilityAtoms::selected ||
       aAttribute == nsAccessibilityAtoms::aria_selected) {
     // ARIA or XUL selection
 
     nsAccessible *multiSelect =
       nsAccUtils::GetMultiSelectableContainer(aContent);
     // Multi selects use selection_add and selection_remove
     // Single select widgets just mirror event_selection for
--- a/accessible/tests/mochitest/events/test_aria_statechange.html
+++ b/accessible/tests/mochitest/events/test_aria_statechange.html
@@ -21,65 +21,97 @@
   <script type="application/javascript">
 
 
     /**
      * Do tests.
      */
     var gQueue = null;
 
+    // Debug stuff.
+    //gA11yEventDumpID = "eventdump";
+    // gA11yEventDumpToConsole = true;
+
     function expandNode(aNodeOrID, bExpand)
     {
       this.DOMNode = getNode(aNodeOrID);
 
-      this.invoke = function expand_invoke() {
+      this.invoke = function expandNode_invoke() {
         // Note: this should fire an EVENT_STATE_CHANGE
         this.DOMNode.setAttribute("aria-expanded", bExpand);
       };
 
-      this.check = function expand_check() {
+      this.check = function expandNode_check() {
         testStates(aNodeOrID,
                    bExpand ? STATE_EXPANDED : STATE_COLLAPSED,
                    EXT_STATE_EXPANDABLE);
       };
 
-      this.getID = function changeValue_getID() {
+      this.getID = function expandNode_getID() {
         return prettyName(aNodeOrID) + " aria-expanded changed";
       };
     }
 
+    function busyify(aNodeOrID, aBusy)
+    {
+      this.DOMNode = getNode(aNodeOrID);
+
+      this.invoke = function busyify_invoke() {
+        this.DOMNode.setAttribute("aria-busy", aBusy);
+      };
+
+      this.check = function busyify_check(event) {
+        testStates(aNodeOrID,
+                   (aBusy ? STATE_BUSY : 0), 0,
+                   (aBusy ? 0 : STATE_BUSY), 0);
+      };
+
+      this.getID = function busyify_getID() {
+        return prettyName(aNodeOrID) + " aria-busy changed to " + aBusy;
+      };
+    }
+
     function doTests()
     {
-      gQueue = new eventQueue(nsIAccessibleEvent.EVENT_STATE_CHANGE);
+      gQueue = new eventQueue(EVENT_STATE_CHANGE);
 
       gQueue.push(new expandNode("section", true));
       gQueue.push(new expandNode("section", false));
       gQueue.push(new expandNode("div", true));
       gQueue.push(new expandNode("div", false));
 
+      gQueue.push(new busyify("aria_doc", true));
+      gQueue.push(new busyify("aria_doc", false));
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTests);
   </script>
 </head>
 
 <body>
 
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=551684"
      title="No statechange event for aria-expanded on native HTML elements, is fired on ARIA widgets">
     Mozilla Bug 551684
   </a>
 
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=648133"
+     title="fire state change event for aria-busy"
+    Mozilla Bug 648133
+  </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
   <div id="eventdump"></div>
 
   <!-- aria-expanded -->
   <div id="section" role="section" aria-expanded="false">expandable section</div>
   <div id="div" aria-expanded="false">expandable native div</div>
 
+  <!-- aria-busy -->
+  <div id="aria_doc" role="document" tabindex="0">A document</div>
 </body>
 </html>
--- a/accessible/tests/mochitest/states/Makefile.in
+++ b/accessible/tests/mochitest/states/Makefile.in
@@ -43,16 +43,17 @@ VPATH		= @srcdir@
 relativesrcdir  = accessible/states
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _TEST_FILES =\
 		test_aria.html \
 		test_aria_imgmap.html \
+		test_aria_tabs.html \
 		test_doc.html \
 		test_docarticle.html \
 		test_editablebody.html \
 		test_frames.html \
 		test_inputs.html \
 		test_inputs.xul \
 		test_link.html \
 		test_popup.xul \
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/states/test_aria_tabs.html
@@ -0,0 +1,137 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+  <title>Test ARIA tab accessible selected state</title>
+
+  <link rel="stylesheet" type="text/css"
+        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/MochiKit/packed.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+  <script type="application/javascript"
+          src="../common.js"></script>
+  <script type="application/javascript"
+          src="../states.js"></script>
+  <script type="application/javascript"
+          src="../events.js"></script>
+
+  <script type="application/javascript">
+    function focusARIATab(aID, aIsSelected)
+    {
+      this.DOMNode = getNode(aID);
+
+      this.invoke = function focusARIATab_invoke()
+      {
+        this.DOMNode.focus();
+      }
+
+      this.check = function focusARIATab_check(aEvent)
+      {
+        testStates(this.DOMNode, aIsSelected ? STATE_SELECTED : 0, 0,
+                   aIsSelected ? 0 : STATE_SELECTED);
+      }
+
+      this.getID = function focusARIATab_getID()
+      {
+        return "Focused ARIA Tab with aria-selected=" +
+                (aIsSelected ? "true, should" : "false, shouldn't") +
+                " have selected state on " + prettyName(aID);
+      }
+    }
+
+    function focusActiveDescendantTab(aTabID, aTabListID, aIsSelected)
+    {
+      this.DOMNode = getNode(aTabID);
+      this.tabListDOMNode = getNode(aTabListID);
+
+      this.invoke = function focusActiveDescendantTab_invoke()
+      {
+        this.tabListDOMNode.setAttribute("aria-activedescendant", aTabID);
+        this.tabListDOMNode.focus();
+      }
+
+      this.check = function focusActiveDescendantTab_check(aEvent)
+      {
+        testStates(this.DOMNode, aIsSelected ? STATE_SELECTED : 0, 0,
+                   aIsSelected ? 0 : STATE_SELECTED);
+      }
+
+      this.getID = function tabActiveDescendant_getID()
+      {
+        return "ARIA Tab with activedescendant " +
+                (aIsSelected ? "should" : "shouldn't") +
+                " have the selected state on " + prettyName(aTabID);
+      }
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    // Test
+
+    //gA11yEventDumpID = "eventdump"; // debug stuff
+    //gA11yEventDumpToConsole = true;
+
+    var gQueue = null;
+
+    function doTest()
+    {
+      // simple tabs
+      testStates("aria_tab1", 0, 0, STATE_SELECTED);
+      testStates("aria_tab2", STATE_SELECTED);
+
+      // To make sure our focus != selected is truly under test, we need to
+      // make sure our cache of what currently has focus is correct, which
+      // we update asyncronously.
+      gQueue = new eventQueue(EVENT_FOCUS);
+
+      gQueue.push(new focusARIATab("aria_tab1", true));
+      gQueue.push(new focusARIATab("aria_tab3", false));
+      gQueue.push(new focusARIATab("aria_tab2", true));
+
+      // selection through aria-activedescendant
+      // Make sure initially setting it selects the tab.
+      gQueue.push(new focusActiveDescendantTab("aria_tab5", "aria_tablist2", true));
+
+      // Now, make sure if one is selected selection gets transferred properly.
+      gQueue.push(new focusActiveDescendantTab("aria_tab6", "aria_tablist2", true));
+
+      // Now, make sure the focused but explicitly unselected one behaves.
+      gQueue.push(new focusActiveDescendantTab("aria_tab4", "aria_tablist2", false));
+
+      gQueue.invoke(); // SimpleTest.finish() will be called in the end
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTest);
+  </script>
+</head>
+<body>
+
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=653601"
+     title="aria-selected ignored for ARIA tabs">
+    Mozilla Bug 653601
+  </a>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+
+  <!-- tab -->
+  <div id="aria_tablist" role="tablist">
+    <div id="aria_tab1" role="tab" tabindex="0">unselected tab</div>
+    <div id="aria_tab2" role="tab" tabindex="0" aria-selected="true">selected tab</div>
+    <div id="aria_tab3" role="tab" tabindex="0" aria-selected="false">focused explicitly unselected tab</div>
+  </div>
+  
+  <!-- test activeDescendant -->
+  <div id="aria_tablist2" role="tablist" tabindex="0">
+    <div id="aria_tab4" role="tab" aria-selected="false">focused explicitly unselected tab</div>
+    <div id="aria_tab5" role="tab">initially selected tab</div>
+    <div id="aria_tab6" role="tab">later selected tab</div>
+  </div>
+</body>
+</html>
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -338,17 +338,18 @@
 
     <menupopup id="placesContext"/>
 
     <panel id="notification-popup"
            type="arrow"
            footertype="promobox"
            position="after_start"
            hidden="true"
-           orient="vertical"/>
+           orient="vertical"
+           role="alert"/>
 
     <!-- Popup for site identity information -->
     <panel id="identity-popup"
            type="arrow"
            hidden="true"
            noautofocus="true"
            onpopupshown="document.getElementById('identity-popup-more-info-button').focus();"
            level="top">
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -902,17 +902,17 @@
                             label="&closeNotificationItem.label;"
                             xbl:inherits="oncommand=closeitemcommand"/>
             </xul:menupopup>
           </xul:button>
         </xul:hbox>
       </xul:vbox>
       <xul:vbox pack="start">
         <xul:toolbarbutton anonid="closebutton"
-                           class="messageCloseButton popup-notification-closebutton"
+                           class="messageCloseButton popup-notification-closebutton tabbable"
                            xbl:inherits="oncommand=closebuttoncommand"
                            tooltiptext="&closeNotification.tooltip;"/>
       </xul:vbox>
     </content>
     <implementation>  
       <constructor><![CDATA[
         let link = document.getAnonymousElementByAttribute(this, "anonid", "learnmore");
         link.value = gNavigatorBundle.getString("geolocation.learnMore");
@@ -949,17 +949,17 @@
                             label="&closeNotificationItem.label;"
                             xbl:inherits="oncommand=closeitemcommand"/>
             </xul:menupopup>
           </xul:button>
         </xul:hbox>
       </xul:vbox>
       <xul:vbox pack="start">
         <xul:toolbarbutton anonid="closebutton"
-                           class="messageCloseButton popup-notification-closebutton"
+                           class="messageCloseButton popup-notification-closebutton tabbable"
                            xbl:inherits="oncommand=closebuttoncommand"
                            tooltiptext="&closeNotification.tooltip;"/>
       </xul:vbox>
     </content>
     <implementation>
       <constructor><![CDATA[
         this.cancelbtn.setAttribute("tooltiptext", gNavigatorBundle.getString("addonDownloadCancelTooltip"));
 
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -310,17 +310,16 @@ OS_COMPILE_CXXFLAGS = $(OS_CPPFLAGS) @CO
 OS_INCLUDES	= $(NSPR_CFLAGS) $(NSS_CFLAGS) $(JPEG_CFLAGS) $(PNG_CFLAGS) $(ZLIB_CFLAGS)
 OS_LIBS		= @LIBS@
 ACDEFINES	= @MOZ_DEFINES@
 
 WARNINGS_AS_ERRORS = @WARNINGS_AS_ERRORS@
 
 MOZ_OPTIMIZE	= @MOZ_OPTIMIZE@
 MOZ_OPTIMIZE_FLAGS = @MOZ_OPTIMIZE_FLAGS@
-MOZ_PGO_OPTIMIZE_FLAGS = @MOZ_PGO_OPTIMIZE_FLAGS@
 MOZ_OPTIMIZE_LDFLAGS = @MOZ_OPTIMIZE_LDFLAGS@
 MOZ_OPTIMIZE_SIZE_TWEAK = @MOZ_OPTIMIZE_SIZE_TWEAK@
 
 MOZ_RTTI_FLAGS_ON = @_MOZ_RTTI_FLAGS_ON@
 MOZ_EXCEPTIONS_FLAGS_ON = @_MOZ_EXCEPTIONS_FLAGS_ON@
 
 PROFILE_GEN_CFLAGS = @PROFILE_GEN_CFLAGS@
 PROFILE_GEN_LDFLAGS = @PROFILE_GEN_LDFLAGS@
--- a/config/config.mk
+++ b/config/config.mk
@@ -417,23 +417,18 @@ LDFLAGS		= $(OS_LDFLAGS) $(MOZ_FIX_LINK_
 # by setting MODULE_OPTIMIZE_FLAGS if the developer has not given
 # arguments to --enable-optimize
 ifdef MOZ_OPTIMIZE
 ifeq (1,$(MOZ_OPTIMIZE))
 ifdef MODULE_OPTIMIZE_FLAGS
 CFLAGS		+= $(MODULE_OPTIMIZE_FLAGS)
 CXXFLAGS	+= $(MODULE_OPTIMIZE_FLAGS)
 else
-ifneq (,$(MOZ_PROFILE_GENERATE)$(MOZ_PROFILE_USE))
-CFLAGS		+= $(MOZ_PGO_OPTIMIZE_FLAGS)
-CXXFLAGS	+= $(MOZ_PGO_OPTIMIZE_FLAGS)
-else
 CFLAGS		+= $(MOZ_OPTIMIZE_FLAGS)
 CXXFLAGS	+= $(MOZ_OPTIMIZE_FLAGS)
-endif # neq (,$(MOZ_PROFILE_GENERATE)$(MOZ_PROFILE_USE))
 endif # MODULE_OPTIMIZE_FLAGS
 else
 CFLAGS		+= $(MOZ_OPTIMIZE_FLAGS)
 CXXFLAGS	+= $(MOZ_OPTIMIZE_FLAGS)
 endif # MOZ_OPTIMIZE == 1
 LDFLAGS		+= $(MOZ_OPTIMIZE_LDFLAGS)
 endif # MOZ_OPTIMIZE
 
--- a/configure.in
+++ b/configure.in
@@ -2183,22 +2183,20 @@ ia64*-hpux*)
         GCC_VERSION=`$CC -v 2>&1 | awk '/^gcc version/ { print $3 }'`
         case $GCC_VERSION in
         4.1.*|4.2.*|4.5.*)
             # -Os is broken on gcc 4.1.x 4.2.x, 4.5.x we need to tweak it to get good results.
             MOZ_OPTIMIZE_SIZE_TWEAK="-finline-limit=50"
         esac
         # If we're building with --enable-profiling, we need a frame pointer.
         if test -z "$MOZ_PROFILING"; then
-            MOZ_FRAMEPTR_FLAGS="-fomit-frame-pointer"
+            MOZ_OPTIMIZE_FLAGS="-O3 -fomit-frame-pointer"
         else
-            MOZ_FRAMEPTR_FLAGS="-fno-omit-frame-pointer"
+            MOZ_OPTIMIZE_FLAGS="-O3 -fno-omit-frame-pointer"
         fi
-        MOZ_PGO_OPTIMIZE_FLAGS="-O3 $MOZ_FRAMEPTR_FLAGS"
-        MOZ_OPTIMIZE_FLAGS="-Os -freorder-blocks $MOZ_OPTIMIZE_SIZE_TWEAK $MOZ_FRAMEPTR_FLAGS"
         MOZ_DEBUG_FLAGS="-g"
     fi
 
     TARGET_NSPR_MDCPUCFG='\"md/_linux.cfg\"'
 
     MOZ_MEMORY=1
 
     case "${target_cpu}" in
@@ -6135,36 +6133,39 @@ if test -n "$MOZ_ANGLE"; then
 
   # Get the SDK path from the registry.
   # First try to get the June 2010 SDK
   MOZ_DIRECTX_SDK_REG_KEY=`reg query 'HKLM\Software\Microsoft\DirectX' //s | grep 'Microsoft DirectX SDK (June 2010)' | head -n 1`
   if test -z "$MOZ_DIRECTX_SDK_REG_KEY" ; then
     # Otherwise just take whatever comes first
     MOZ_DIRECTX_SDK_REG_KEY=`reg query 'HKLM\Software\Microsoft\DirectX' //s | grep 'Microsoft DirectX SDK' | head -n 1`
   fi
-  echo "MOZ_DIRECTX_SDK_REG_KEY=$MOZ_DIRECTX_SDK_REG_KEY"
-  MOZ_DIRECTX_SDK_PATH=`reg query "$MOZ_DIRECTX_SDK_REG_KEY" //v InstallPath | grep REG_SZ | sed 's/.*\([[a-zA-Z]]\)\\:\\\\/\\1\\:\\\\/'`
-  echo "MOZ_DIRECTX_SDK_PATH=$MOZ_DIRECTX_SDK_PATH"
+
+  if test -n "`echo $MOZ_DIRECTX_SDK_REG_KEY | grep 'February 2010'`" ; then
+    AC_MSG_WARN([Found the February 2010 DirectX SDK. This is too old. We now require the June 2010 DirectX SDK, or newer.])
+  else
+    MOZ_DIRECTX_SDK_PATH=`reg query "$MOZ_DIRECTX_SDK_REG_KEY" //v InstallPath | grep REG_SZ | sed 's/.*\([[a-zA-Z]]\)\\:\\\\/\\1\\:\\\\/'`
+  fi
 
   MOZ_ANGLE=
 
   if test -n "$MOZ_DIRECTX_SDK_PATH" ; then
     if test -f "$MOZ_DIRECTX_SDK_PATH"/include/d3dx9.h && test -f "$MOZ_DIRECTX_SDK_PATH"/lib/$MOZ_DIRECTX_SDK_CPU_SUFFIX/dxguid.lib ; then
       AC_MSG_RESULT([Found DirectX SDK via registry, using $MOZ_DIRECTX_SDK_PATH])
       MOZ_ANGLE=1
     fi
   fi
 
   if test -z "$MOZ_ANGLE" ; then
-    AC_MSG_WARN([Couldn't find the DirectX SDK, needed for ANGLE. Please install it (February 2010 or newer). To explicitly build without ANGLE, reconfigure with --disable-angle.])
+    AC_MSG_WARN([Couldn't find the DirectX SDK, needed for ANGLE. Please install it (June 2010 or newer). To explicitly build without ANGLE, reconfigure with --disable-angle.])
     AC_MSG_WARN([This will become an error in the future.])
   fi
 
   if test -n "$MOZ_ANGLE" ; then
-    # Get the SDK numeric version (e.g. 42 or 43) by looking at the dependencies of d3dx9.lib
+    # Get the SDK numeric version (e.g. 43) by looking at the dependencies of d3dx9.lib
     MOZ_D3DX9_VERSION=`dumpbin //headers "$MOZ_DIRECTX_SDK_PATH"/lib/$MOZ_DIRECTX_SDK_CPU_SUFFIX/d3dx9.lib | egrep d3dx9_[[0-9]][[0-9]]\.dll | head -n1 | sed 's/.*\([[0-9]][[0-9]]\).*/\\1/g'`
 
     if test -z "$MOZ_D3DX9_VERSION" ; then
       MOZ_ANGLE=
       AC_MSG_WARN([Couldn't determine the D3DX9 version! Disabling ANGLE.])
       AC_MSG_WARN([This will become an error in the future.])
     fi
 
@@ -7180,17 +7181,16 @@ if test -n "$MOZ_OPTIMIZE"; then
     CFLAGS=$_SAVE_CFLAGS
 fi
 fi # COMPILE_ENVIRONMENT
 
 AC_SUBST(MOZ_OPTIMIZE)
 AC_SUBST(MOZ_OPTIMIZE_FLAGS)
 AC_SUBST(MOZ_OPTIMIZE_LDFLAGS)
 AC_SUBST(MOZ_OPTIMIZE_SIZE_TWEAK)
-AC_SUBST(MOZ_PGO_OPTIMIZE_FLAGS)
 
 dnl ========================================================
 dnl = Enable generation of debug symbols
 dnl ========================================================
 MOZ_ARG_ENABLE_STRING(debug-symbols,
 [  --enable-debug-symbols[=DBG]
                           Enable debugging symbols (using compiler flags DBG)],
 [ if test "$enableval" != "no"; then
--- a/content/base/public/nsIDOMFileReader.idl
+++ b/content/base/public/nsIDOMFileReader.idl
@@ -36,34 +36,31 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsIDOMEventTarget.idl"
 
 interface nsIDOMEventListener;
 interface nsIDOMBlob;
 interface nsIDOMFileError;
 
-[scriptable, uuid(3d77e784-1459-4206-b8a2-0855d826f569)]
+[scriptable, uuid(f186170f-f07c-4f0b-9e3c-08f7dd496e74)]
 interface nsIDOMFileReader : nsISupports 
 {
-  [implicit_jscontext]
-  void readAsArrayBuffer(in nsIDOMBlob filedata);
   void readAsBinaryString(in nsIDOMBlob filedata);
   void readAsText(in nsIDOMBlob filedata, [optional] in DOMString encoding);
   void readAsDataURL(in nsIDOMBlob file);
 
   void abort();
 
   const unsigned short EMPTY = 0;
   const unsigned short LOADING = 1;
   const unsigned short DONE = 2;
   readonly attribute unsigned short readyState;
 
-  [implicit_jscontext]
-  readonly attribute jsval result;
+  readonly attribute DOMString result;
   readonly attribute nsIDOMFileError error;
 };
 
 %{ C++
 #define NS_FILEREADER_CID                            \
 {0x06aa7c21, 0xfe05, 0x4cf2,                         \
 {0xb1, 0xc4, 0x0c, 0x71, 0x26, 0xa4, 0xf7, 0x13}}
 #define NS_FILEREADER_CONTRACTID \
--- a/content/base/src/nsDOMFileReader.cpp
+++ b/content/base/src/nsDOMFileReader.cpp
@@ -72,19 +72,16 @@
 #include "nsIDOMClassInfo.h"
 #include "nsCExternalHandlerService.h"
 #include "nsIStreamConverterService.h"
 #include "nsEventDispatcher.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsLayoutStatics.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsFileDataProtocolHandler.h"
-#include "xpcprivate.h"
-#include "xpcquickstubs.h"
-#include "jstypedarray.h"
 
 #define LOAD_STR "load"
 #define ERROR_STR "error"
 #define ABORT_STR "abort"
 #define LOADSTART_STR "loadstart"
 #define PROGRESS_STR "progress"
 #define UPLOADPROGRESS_STR "uploadprogress"
 #define LOADEND_STR "loadend"
@@ -99,76 +96,58 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFile)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mProgressNotifier)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mPrincipal)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mChannel)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMFileReader,
                                                 nsXHREventTarget)
-  tmp->mResultArrayBuffer = nsnull;
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFile)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mProgressNotifier)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mPrincipal)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mChannel)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(nsDOMFileReader,
-                                               nsXHREventTarget)
-  if(tmp->mResultArrayBuffer) {
-    NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(tmp->mResultArrayBuffer,
-                                               "mResultArrayBuffer")
-  }
-NS_IMPL_CYCLE_COLLECTION_TRACE_END
-
 DOMCI_DATA(FileReader, nsDOMFileReader)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMFileReader)
   NS_INTERFACE_MAP_ENTRY(nsIDOMFileReader)
   NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
   NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
   NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
   NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
   NS_INTERFACE_MAP_ENTRY(nsICharsetDetectionObserver)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(FileReader)
 NS_INTERFACE_MAP_END_INHERITING(nsXHREventTarget)
 
 NS_IMPL_ADDREF_INHERITED(nsDOMFileReader, nsXHREventTarget)
 NS_IMPL_RELEASE_INHERITED(nsDOMFileReader, nsXHREventTarget)
 
-//array buffer holder root/unroot
-void
-nsDOMFileReader::RootResultArrayBuffer()
-{
-  nsContentUtils::PreserveWrapper(static_cast<nsPIDOMEventTarget*>(this), this);
-}
-
 //nsICharsetDetectionObserver
 
 NS_IMETHODIMP
 nsDOMFileReader::Notify(const char *aCharset, nsDetectionConfident aConf)
 {
   mCharset = aCharset;
   return NS_OK;
 }
 
 //nsDOMFileReader constructors/initializers
 
 nsDOMFileReader::nsDOMFileReader()
   : mFileData(nsnull),
     mDataLen(0), mDataFormat(FILE_AS_BINARY),
-    mResultArrayBuffer(nsnull),
     mReadyState(nsIDOMFileReader::EMPTY),
     mProgressEventWasDelayed(PR_FALSE),
     mTimerIsActive(PR_FALSE),
     mReadTotal(0), mReadTransferred(0)
 {
   nsLayoutStatics::AddRef();
-  SetDOMStringToNull(mResult);
 }
 
 nsDOMFileReader::~nsDOMFileReader()
 {
   if (mListenerManager) 
     mListenerManager->Disconnect();
 
   FreeFileData();
@@ -251,64 +230,46 @@ nsDOMFileReader::GetInterface(const nsII
 NS_IMETHODIMP
 nsDOMFileReader::GetReadyState(PRUint16 *aReadyState)
 {
   *aReadyState = mReadyState;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMFileReader::GetResult(JSContext* aCx, jsval* aResult)
+nsDOMFileReader::GetResult(nsAString& aResult)
 {
-  if (mDataFormat == FILE_AS_ARRAYBUFFER) {
-    if (mReadyState == nsIDOMFileReader::DONE) {
-      *aResult = OBJECT_TO_JSVAL(mResultArrayBuffer);
-    } else {
-      *aResult = JSVAL_NULL;
-    }
-    return NS_OK;
-  }
- 
-  nsString tmpResult = mResult;
-  if (!xpc_qsStringToJsval(aCx, tmpResult, aResult)) {
-    return NS_ERROR_FAILURE;
-  }
+  aResult = mResult;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMFileReader::GetError(nsIDOMFileError** aError)
 {
   NS_IF_ADDREF(*aError = mError);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMFileReader::ReadAsArrayBuffer(nsIDOMBlob* aFile, JSContext* aCx)
-{
-  return ReadFileContent(aCx, aFile, EmptyString(), FILE_AS_ARRAYBUFFER);
-}
-
-NS_IMETHODIMP
 nsDOMFileReader::ReadAsBinaryString(nsIDOMBlob* aFile)
 {
-  return ReadFileContent(nsnull, aFile, EmptyString(), FILE_AS_BINARY);
+  return ReadFileContent(aFile, EmptyString(), FILE_AS_BINARY);
 }
 
 NS_IMETHODIMP
 nsDOMFileReader::ReadAsText(nsIDOMBlob* aFile,
                             const nsAString &aCharset)
 {
-  return ReadFileContent(nsnull, aFile, aCharset, FILE_AS_TEXT);
+  return ReadFileContent(aFile, aCharset, FILE_AS_TEXT);
 }
 
 NS_IMETHODIMP
 nsDOMFileReader::ReadAsDataURL(nsIDOMBlob* aFile)
 {
-  return ReadFileContent(nsnull, aFile, EmptyString(), FILE_AS_DATAURL);
+  return ReadFileContent(aFile, EmptyString(), FILE_AS_DATAURL);
 }
 
 NS_IMETHODIMP
 nsDOMFileReader::Abort()
 {
   if (mReadyState != nsIDOMFileReader::LOADING)
     return NS_ERROR_DOM_FILE_ABORT_ERR;
 
@@ -316,17 +277,16 @@ nsDOMFileReader::Abort()
   mProgressEventWasDelayed = PR_FALSE;
   mTimerIsActive = PR_FALSE;
   if (mProgressNotifier) {
     mProgressNotifier->Cancel();
   }
 
   //Revert status, result and readystate attributes
   SetDOMStringToNull(mResult);
-  mResultArrayBuffer = nsnull;
   mReadyState = nsIDOMFileReader::DONE;
   mError = new nsDOMFileError(nsIDOMFileError::ABORT_ERR);
     
   //Non-null channel indicates a read is currently active
   if (mChannel) {
     //Cancel request requires an error status
     mChannel->Cancel(NS_ERROR_FAILURE);
     mChannel = nsnull;
@@ -419,24 +379,16 @@ nsDOMFileReader::OnDataAvailable(nsIRequ
     mResult.GetMutableData(&buf, oldLen + aCount);
     NS_ENSURE_TRUE(buf, NS_ERROR_OUT_OF_MEMORY);
 
     PRUint32 bytesRead = 0;
     aInputStream->ReadSegments(ReadFuncBinaryString, buf + oldLen, aCount,
                                &bytesRead);
     NS_ASSERTION(bytesRead == aCount, "failed to read data");
   }
-  else if (mDataFormat == FILE_AS_ARRAYBUFFER) {
-    js::ArrayBuffer* abuf = js::ArrayBuffer::fromJSObject(mResultArrayBuffer);
-    NS_ASSERTION(abuf, "What happened?");
-  
-    PRUint32 bytesRead = 0;
-    aInputStream->Read((char*)abuf->data + aOffset, aCount, &bytesRead);
-    NS_ASSERTION(bytesRead == aCount, "failed to read data");
-  }
   else {
     //Update memory buffer to reflect the contents of the file
     mFileData = (char *)PR_Realloc(mFileData, aOffset + aCount);
     NS_ENSURE_TRUE(mFileData, NS_ERROR_OUT_OF_MEMORY);
 
     PRUint32 bytesRead = 0;
     aInputStream->Read(mFileData + aOffset, aCount, &bytesRead);
     NS_ASSERTION(bytesRead == aCount, "failed to read data");
@@ -482,18 +434,16 @@ nsDOMFileReader::OnStopRequest(nsIReques
   if (NS_FAILED(aStatus)) {
     FreeFileData();
     DispatchError(aStatus);
     return NS_OK;
   }
 
   nsresult rv = NS_OK;
   switch (mDataFormat) {
-    case FILE_AS_ARRAYBUFFER:
-      break; //Already accumulated mResultArrayBuffer
     case FILE_AS_BINARY:
       break; //Already accumulated mResult
     case FILE_AS_TEXT:
       rv = GetAsText(mCharset, mFileData, mDataLen, mResult);
       break;
     case FILE_AS_DATAURL:
       rv = GetAsDataURL(mFile, mFileData, mDataLen, mResult);
       break;
@@ -513,18 +463,17 @@ nsDOMFileReader::OnStopRequest(nsIReques
   DispatchProgressEvent(NS_LITERAL_STRING(LOADEND_STR));
 
   return NS_OK;
 }
 
 // Helper methods
 
 nsresult
-nsDOMFileReader::ReadFileContent(JSContext* aCx,
-                                 nsIDOMBlob* aFile,
+nsDOMFileReader::ReadFileContent(nsIDOMBlob* aFile,
                                  const nsAString &aCharset,
                                  eDataFormat aDataFormat)
 {
   nsresult rv;
   NS_ENSURE_TRUE(aFile, NS_ERROR_NULL_POINTER);
 
   //Implicit abort to clear any other activity going on
   Abort();
@@ -559,25 +508,16 @@ nsDOMFileReader::ReadFileContent(JSConte
   mFile->GetSize(&mReadTotal);
 
   rv = mChannel->AsyncOpen(this, nsnull);
   NS_ENSURE_SUCCESS(rv, rv);
 
   //FileReader should be in loading state here
   mReadyState = nsIDOMFileReader::LOADING;
   DispatchProgressEvent(NS_LITERAL_STRING(LOADSTART_STR));
-  
-  if (mDataFormat == FILE_AS_ARRAYBUFFER) {
-    RootResultArrayBuffer();
-    mResultArrayBuffer = js_CreateArrayBuffer(aCx, mReadTotal);
-    if (!mResultArrayBuffer) {
-      NS_WARNING("Failed to create JS array buffer");
-      return NS_ERROR_FAILURE;
-    }
-  }
  
   return NS_OK;
 }
 
 void
 nsDOMFileReader::DispatchError(nsresult rv)
 {
   //Set the status attribute, and dispatch the error event
--- a/content/base/src/nsDOMFileReader.h
+++ b/content/base/src/nsDOMFileReader.h
@@ -75,18 +75,17 @@ class nsDOMFileReader : public nsXHREven
 {
 public:
   nsDOMFileReader();
   virtual ~nsDOMFileReader();
 
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_NSIDOMFILEREADER
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(nsDOMFileReader,
-                                                         nsXHREventTarget)
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMFileReader, nsXHREventTarget)
 
   NS_FORWARD_NSIXMLHTTPREQUESTEVENTTARGET(nsXHREventTarget::);
         
   // nsIStreamListener
   NS_DECL_NSISTREAMLISTENER
                                
   // nsIRequestObserver
   NS_DECL_NSIREQUESTOBSERVER
@@ -105,28 +104,25 @@ public:
   NS_FORWARD_NSIDOMNSEVENTTARGET(nsXHREventTarget::)
 
   // nsICharsetDetectionObserver
   NS_IMETHOD Notify(const char *aCharset, nsDetectionConfident aConf);
 
   void DispatchProgressEvent(const nsAString& aType);
 
   nsresult Init();
-  
-  void RootResultArrayBuffer();
 
 protected:
   enum eDataFormat {
-    FILE_AS_ARRAYBUFFER,
     FILE_AS_BINARY,
     FILE_AS_TEXT,
     FILE_AS_DATAURL
   };
 
-  nsresult ReadFileContent(JSContext* aCx, nsIDOMBlob *aFile, const nsAString &aCharset, eDataFormat aDataFormat); 
+  nsresult ReadFileContent(nsIDOMBlob *aFile, const nsAString &aCharset, eDataFormat aDataFormat); 
   nsresult GetAsText(const nsACString &aCharset,
                      const char *aFileData, PRUint32 aDataLen, nsAString &aResult);
   nsresult GetAsDataURL(nsIDOMBlob *aFile, const char *aFileData, PRUint32 aDataLen, nsAString &aResult); 
   nsresult GuessCharset(const char *aFileData, PRUint32 aDataLen, nsACString &aCharset); 
   nsresult ConvertStream(const char *aFileData, PRUint32 aDataLen, const char *aCharset, nsAString &aResult); 
   void DispatchError(nsresult rv);
   void StartProgressEventTimer();
 
@@ -138,18 +134,16 @@ protected:
 
   char *mFileData;
   nsCOMPtr<nsIDOMBlob> mFile;
   nsCString mCharset;
   PRUint32 mDataLen;
 
   eDataFormat mDataFormat;
 
-  JSObject* mResultArrayBuffer;
-  
   nsString mResult;
   PRUint16 mReadyState;
 
   PRBool mProgressEventWasDelayed;
   PRBool mTimerIsActive;
   nsCOMPtr<nsIDOMFileError> mError;
 
   nsCOMPtr<nsITimer> mProgressNotifier;
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -421,18 +421,17 @@ NS_IMPL_RELEASE_INHERITED(nsXMLHttpReque
 nsXMLHttpRequest::nsXMLHttpRequest()
   : mResponseType(XML_HTTP_RESPONSE_TYPE_DEFAULT),
     mRequestObserver(nsnull), mState(XML_HTTP_REQUEST_UNSENT),
     mUploadTransferred(0), mUploadTotal(0), mUploadComplete(PR_TRUE),
     mUploadProgress(0), mUploadProgressMax(0),
     mErrorLoad(PR_FALSE), mTimerIsActive(PR_FALSE),
     mProgressEventWasDelayed(PR_FALSE),
     mLoadLengthComputable(PR_FALSE), mLoadTotal(0),
-    mFirstStartRequestSeen(PR_FALSE),
-    mResultArrayBuffer(nsnull) 
+    mFirstStartRequestSeen(PR_FALSE)
 {
   mResponseBodyUnicode.SetIsVoid(PR_TRUE);
   nsLayoutStatics::AddRef();
 }
 
 nsXMLHttpRequest::~nsXMLHttpRequest()
 {
   if (mListenerManager) {
@@ -446,22 +445,16 @@ nsXMLHttpRequest::~nsXMLHttpRequest()
   }
 
   NS_ABORT_IF_FALSE(!(mState & XML_HTTP_REQUEST_SYNCLOOPING), "we rather crash than hang");
   mState &= ~XML_HTTP_REQUEST_SYNCLOOPING;
 
   nsLayoutStatics::Release();
 }
 
-void
-nsXMLHttpRequest::RootResultArrayBuffer()
-{
-  nsContentUtils::PreserveWrapper(static_cast<nsPIDOMEventTarget*>(this), this);
-}
-
 /**
  * This Init method is called from the factory constructor.
  */
 nsresult
 nsXMLHttpRequest::Init()
 {
   // Set the original mScriptContext and mPrincipal, if available.
   // Get JSContext from stack.
@@ -574,19 +567,19 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
 
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mChannelEventSink)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mProgressEventSink)
 
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mUpload,
                                                        nsIXMLHttpRequestUpload)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
+
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXMLHttpRequest,
                                                 nsXHREventTarget)
-  tmp->mResultArrayBuffer = nsnull;
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mContext)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mChannel)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mReadRequest)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mResponseXML)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCORSPreflightChannel)
 
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnUploadProgressListener)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnReadystatechangeListener)
@@ -594,24 +587,16 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_IN
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mXMLParserStreamListener)
 
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mChannelEventSink)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mProgressEventSink)
 
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mUpload)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(nsXMLHttpRequest,
-                                               nsXHREventTarget)
-  if(tmp->mResultArrayBuffer) {
-    NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(tmp->mResultArrayBuffer,
-                                               "mResultArrayBuffer")
-  }
-NS_IMPL_CYCLE_COLLECTION_TRACE_END
-
 DOMCI_DATA(XMLHttpRequest, nsXMLHttpRequest)
 
 // QueryInterface implementation for nsXMLHttpRequest
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsXMLHttpRequest)
   NS_INTERFACE_MAP_ENTRY(nsIXMLHttpRequest)
   NS_INTERFACE_MAP_ENTRY(nsIJSXMLHttpRequest)
   NS_INTERFACE_MAP_ENTRY(nsIDOMLoadListener)
   NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener)
@@ -849,30 +834,37 @@ NS_IMETHODIMP nsXMLHttpRequest::GetRespo
   if (mState & (XML_HTTP_REQUEST_DONE |
                 XML_HTTP_REQUEST_LOADING)) {
     rv = ConvertBodyToText(aResponseText);
   }
 
   return rv;
 }
 
-nsresult nsXMLHttpRequest::CreateResponseArrayBuffer(JSContext *aCx)
+nsresult nsXMLHttpRequest::GetResponseArrayBuffer(jsval *aResult)
 {
-  if (!aCx)
+  JSContext *cx = nsContentUtils::GetCurrentJSContext();
+  if (!cx)
     return NS_ERROR_FAILURE;
 
+  if (!(mState & (XML_HTTP_REQUEST_DONE |
+                  XML_HTTP_REQUEST_LOADING))) {
+    *aResult = JSVAL_NULL;
+    return NS_OK;
+  }
+
   PRInt32 dataLen = mResponseBody.Length();
-  RootResultArrayBuffer();
-  mResultArrayBuffer = js_CreateArrayBuffer(aCx, dataLen);
-  if (!mResultArrayBuffer) {
+  JSObject *obj = js_CreateArrayBuffer(cx, dataLen);
+  if (!obj)
     return NS_ERROR_FAILURE;
-  }
+
+  *aResult = OBJECT_TO_JSVAL(obj);
 
   if (dataLen > 0) {
-    js::ArrayBuffer *abuf = js::ArrayBuffer::fromJSObject(mResultArrayBuffer);
+    js::ArrayBuffer *abuf = js::ArrayBuffer::fromJSObject(obj);
     NS_ASSERTION(abuf, "What happened?");
     memcpy(abuf->data, mResponseBody.BeginReading(), dataLen);
   }
 
   return NS_OK;
 }
 
 /* attribute AString responseType; */
@@ -957,21 +949,17 @@ NS_IMETHODIMP nsXMLHttpRequest::GetRespo
       if (buf) {
         str.ForgetSharedBuffer();
       }
     }
     break;
 
   case XML_HTTP_RESPONSE_TYPE_ARRAYBUFFER:
     if (mState & XML_HTTP_REQUEST_DONE) {
-      if (!mResultArrayBuffer) {  
-         rv = CreateResponseArrayBuffer(aCx);
-         NS_ENSURE_SUCCESS(rv, rv);
-      }
-      *aResult = OBJECT_TO_JSVAL(mResultArrayBuffer);
+      rv = GetResponseArrayBuffer(aResult);
     } else {
       *aResult = JSVAL_NULL;
     }
     break;
 
   case XML_HTTP_RESPONSE_TYPE_BLOB:
     if (mState & XML_HTTP_REQUEST_DONE && mResponseBlob) {
       JSObject* scope = JS_GetScopeChain(aCx);
@@ -1080,18 +1068,17 @@ nsXMLHttpRequest::Abort()
     mCORSPreflightChannel->Cancel(NS_BINDING_ABORTED);
   }
   mResponseXML = nsnull;
   PRUint32 responseLength = mResponseBody.Length();
   mResponseBody.Truncate();
   mResponseBodyUnicode.SetIsVoid(PR_TRUE);
   mResponseBlob = nsnull;
   mState |= XML_HTTP_REQUEST_ABORTED;
-  mResultArrayBuffer = nsnull;
-  
+
   if (!(mState & (XML_HTTP_REQUEST_UNSENT |
                   XML_HTTP_REQUEST_OPENED |
                   XML_HTTP_REQUEST_DONE))) {
     ChangeState(XML_HTTP_REQUEST_DONE, PR_TRUE);
   }
 
   if (!(mState & XML_HTTP_REQUEST_SYNCLOOPING)) {
     NS_NAMED_LITERAL_STRING(abortStr, ABORT_STR);
--- a/content/base/src/nsXMLHttpRequest.h
+++ b/content/base/src/nsXMLHttpRequest.h
@@ -203,33 +203,33 @@ public:
                           aLoaded, aLengthComputable ? aTotal : LL_MAXUINT);
   }
 
   // This is called by the factory constructor.
   nsresult Init();
 
   void SetRequestObserver(nsIRequestObserver* aObserver);
 
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(nsXMLHttpRequest,
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXMLHttpRequest,
                                            nsXHREventTarget)
+
   PRBool AllowUploadProgress();
-  void RootResultArrayBuffer();
-  
+
 protected:
   friend class nsMultipartProxyListener;
 
   nsresult DetectCharset(nsACString& aCharset);
   nsresult ConvertBodyToText(nsAString& aOutBuffer);
   static NS_METHOD StreamReaderFunc(nsIInputStream* in,
                 void* closure,
                 const char* fromRawSegment,
                 PRUint32 toOffset,
                 PRUint32 count,
                 PRUint32 *writeCount);
-  nsresult CreateResponseArrayBuffer(JSContext* aCx);
+  nsresult GetResponseArrayBuffer(jsval *aResult);
   void CreateResponseBlob(nsIRequest *request);
   // Change the state of the object with this. The broadcast argument
   // determines if the onreadystatechange listener should be called.
   nsresult ChangeState(PRUint32 aState, PRBool aBroadcast = PR_TRUE);
   nsresult RequestCompleted();
   nsresult GetLoadGroup(nsILoadGroup **aLoadGroup);
   nsIURI *GetBaseURI();
 
@@ -340,18 +340,16 @@ protected:
   PRPackedBool mLoadLengthComputable;
   PRUint64 mLoadTotal; // 0 if not known.
   nsCOMPtr<nsITimer> mProgressNotifier;
 
   PRPackedBool mFirstStartRequestSeen;
   
   nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback;
   nsCOMPtr<nsIChannel> mNewRedirectChannel;
-  
-  JSObject* mResultArrayBuffer;
 };
 
 // helper class to expose a progress DOM Event
 
 class nsXMLHttpProgressEvent : public nsIDOMProgressEvent,
                                public nsIDOMLSProgressEvent,
                                public nsIDOMNSEvent,
                                public nsIPrivateDOMEvent
--- a/content/base/test/test_XHR.html
+++ b/content/base/test/test_XHR.html
@@ -129,26 +129,16 @@ xhr.responseType = 'arraybuffer';
 xhr.send(null)
 is(xhr.status, 200, "wrong status");
 checkResponseTextAccessThrows(xhr);
 checkResponseXMLAccessThrows(xhr);
 ab = xhr.response;
 ok(ab != null, "should have a non-null arraybuffer");
 arraybuffer_equals_to(ab, "\xaa\xee\0\x03\xff\xff\xff\xff\xbb\xbb\xbb\xbb");
 
-// test array buffer GetResult returns the same object
-xhr = new XMLHttpRequest();
-xhr.open("GET", 'file_XHR_binary1.bin', false); 
-xhr.responseType = 'arraybuffer';
-xhr.send(null)
-is(xhr.status, 200, "wrong status");
-checkResponseTextAccessThrows(xhr);
-checkResponseXMLAccessThrows(xhr);
-is(xhr.response, xhr.response, "returns the same ArrayBuffer");
-
 // test response (responseType='blob')
 var onloadCount = 0;
 function checkOnloadCount() {
   if (++onloadCount >= 2) SimpleTest.finish();
 };
 
 // with a simple text file
 xhr = new XMLHttpRequest();
--- a/content/base/test/test_fileapi.html
+++ b/content/base/test/test_fileapi.html
@@ -93,28 +93,16 @@ r.addEventListener("load", function() { 
 r.addEventListener("loadstart", function() { onloadStartHasRunBinary = true }, false);
 r.readAsBinaryString(binaryFile);
 r.onload = getLoadHandler(testBinaryData, testBinaryData.length, "binary reading");
 is(r.readyState, FileReader.LOADING, "correct loading binary readyState");
 is(onloadHasRunBinary, false, "binary loading must be async");
 is(onloadStartHasRunBinary, true, "binary loadstart should fire sync");
 expectedTestCount++;
 
-var onloadHasRunArrayBuffer = false;
-var onloadStartHasRunArrayBuffer = false;
-r = new FileReader();
-is(r.readyState, FileReader.EMPTY, "correct initial arrayBuffer readyState");
-r.addEventListener("load", function() { onloadHasRunArrayBuffer = true }, false);
-r.addEventListener("loadstart", function() { onloadStartHasRunArrayBuffer = true }, false);
-r.readAsArrayBuffer(binaryFile);
-r.onload = getLoadHandlerForArrayBuffer(testBinaryData, testBinaryData.length, "array buffer reading");
-is(r.readyState, FileReader.LOADING, "correct loading arrayBuffer readyState");
-is(onloadHasRunArrayBuffer, false, "arrayBuffer loading must be async");
-is(onloadStartHasRunArrayBuffer, true, "arrayBuffer loadstart should fire sync");
-expectedTestCount++;
 
 // Test a variety of encodings, and make sure they work properly
 r = new FileReader();
 r.onload = getLoadHandler(testASCIIData, testASCIIData.length, "no encoding reading");
 r.readAsText(asciiFile, "");
 expectedTestCount++;
 
 r = new FileReader();
@@ -131,24 +119,16 @@ expectedTestCount++;
 
 r = new FileReader();
 r.readAsText(createFileWithData(convertToUTF16(testTextData)), "utf-16");
 r.onload = getLoadHandler(testTextData,
                           convertToUTF16(testTextData).length,
                           "utf16 reading");
 expectedTestCount++;
 
-// Test get result without reading
-r = new FileReader();
-is(r.readyState, FileReader.EMPTY,
-  "readyState in test reader get result without reading");
-is(r.error, null,
-  "no error in test reader get result without reading");
-is(r.result, null,
-  "result in test reader get result without reading");
 
 // Test loading an empty file works (and doesn't crash!)
 var emptyFile = createFileWithData("");
 dump("hello nurse");
 r = new FileReader();
 r.onload = getLoadHandler("", 0, "empty no encoding reading");
 r.readAsText(emptyFile, "");
 expectedTestCount++;
@@ -164,25 +144,21 @@ r.readAsText(emptyFile, "utf-16");
 expectedTestCount++;
 
 r = new FileReader();
 r.onload = getLoadHandler("", 0, "empty binary string reading");
 r.readAsBinaryString(emptyFile);
 expectedTestCount++;
 
 r = new FileReader();
-r.onload = getLoadHandlerForArrayBuffer("", 0, "empty array buffer reading");
-r.readAsArrayBuffer(emptyFile);
-expectedTestCount++;
-
-r = new FileReader();
 r.onload = getLoadHandler(convertToDataURL(""), 0, "empt binary string reading");
 r.readAsDataURL(emptyFile);
 expectedTestCount++;
 
+
 // Test reusing a FileReader to read multiple times
 r = new FileReader();
 r.onload = getLoadHandler(testASCIIData,
                           testASCIIData.length,
                           "to-be-reused reading text")
 var makeAnotherReadListener = function(event) {
   r = event.target;
   r.removeEventListener("load", makeAnotherReadListener, false);
@@ -222,49 +198,16 @@ var makeAnotherReadListener3 = function(
                             testBinaryData.length,
                             "reused reading data url");
   r.readAsDataURL(binaryFile);
 };
 r.addEventListener("load", makeAnotherReadListener3, false);
 r.readAsDataURL(binaryFile);
 expectedTestCount += 2;
 
-r = new FileReader();
-r.onload = getLoadHandlerForArrayBuffer(testBinaryData,
-                          testBinaryData.length,
-                          "to-be-reused reading arrayBuffer")
-var makeAnotherReadListener4 = function(event) {
-  r = event.target;
-  r.removeEventListener("load", makeAnotherReadListener4, false);
-  r.onload = getLoadHandlerForArrayBuffer(testBinaryData,
-                            testBinaryData.length,
-                            "reused reading arrayBuffer");
-  r.readAsArrayBuffer(binaryFile);
-};
-r.addEventListener("load", makeAnotherReadListener4, false);
-r.readAsArrayBuffer(binaryFile);
-expectedTestCount += 2;
-
-// Test first reading as ArrayBuffer then read as something else
-// (BinaryString) and doesn't crash
-r = new FileReader();
-r.onload = getLoadHandlerForArrayBuffer(testBinaryData,
-                          testBinaryData.length,
-                          "to-be-reused reading arrayBuffer")
-var makeAnotherReadListener5 = function(event) {
-  r = event.target;
-  r.removeEventListener("load", makeAnotherReadListener5, false);
-  r.onload = getLoadHandler(testBinaryData,
-                            testBinaryData.length,
-                            "reused reading binary string");
-  r.readAsBinaryString(binaryFile);
-};
-r.addEventListener("load", makeAnotherReadListener5, false);
-r.readAsArrayBuffer(binaryFile);
-expectedTestCount += 2;
 
 //Test data-URI encoding on differing file sizes
 dataurldata = testBinaryData.substr(0, testBinaryData.length -
                                        testBinaryData.length % 3);
 is(dataurldata.length % 3, 0, "Want to test data with length % 3 == 0");
 r = new FileReader();
 r.onload = getLoadHandler(convertToDataURL(dataurldata),
                           dataurldata.length,
@@ -374,47 +317,19 @@ function getLoadHandler(expectedResult, 
        "readyState in test " + testName);
     is(event.target.error, null,
        "no error in test " + testName);
     is(event.target.result, expectedResult,
        "result in test " + testName);
     is(event.lengthComputable, true,
        "lengthComputable in test " + testName);
     is(event.loaded, expectedLength,
-       "loaded in test " + testName);
-    is(event.total, expectedLength,
-       "total in test " + testName);
-    testHasRun();
-  }
-}
-
-function getLoadHandlerForArrayBuffer(expectedResult, expectedLength, testName) {
-  return function (event) {
-    is(event.target.readyState, FileReader.DONE,
-       "readyState in test " + testName);
-    is(event.target.error, null,
-       "no error in test " +  testName);
-    is(event.lengthComputable, true,
        "lengthComputable in test " + testName);
-    is(event.loaded, expectedLength,
-       "loaded in test " + testName);
     is(event.total, expectedLength,
-       "total in test " + testName);
-    is(event.target.result.byteLength, expectedLength,
-       "array buffer size in test " + testName);
-    var u8v = new Uint8Array(event.target.result);
-    is(String.fromCharCode.apply(String, u8v), expectedResult,
-       "array buffer contents in test " + testName);
-    u8v = null;
-    SpecialPowers.gc();
-    is(event.target.result.byteLength, expectedLength,
-       "array buffer size after gc in test " + testName);
-    u8v = new Uint8Array(event.target.result);
-    is(String.fromCharCode.apply(String, u8v), expectedResult,
-       "array buffer contents after gc in test " + testName);
+       "lengthComputable in test " + testName);
     testHasRun();
   }
 }
 
 function testHasRun() {
  //alert(testRanCounter);
  ++testRanCounter;
  if (testRanCounter == expectedTestCount) {
--- a/content/canvas/test/webgl/conformance/glsl-conformance.html
+++ b/content/canvas/test/webgl/conformance/glsl-conformance.html
@@ -530,23 +530,23 @@ if (!gl) {
     },
     //{ vShaderId: 'vshader',
     //  vShaderSuccess: true,
     //  fShaderId: 'fshaderWith257CharacterIdentifier',
     //  fShaderSuccess: false,
     //  linkSuccess: false,
     //  passMsg: 'shader that uses 257 character identifier should fail',
     //},
-    { vShaderId: 'vshader',
-      vShaderSuccess: true,
-      fShaderId: 'fshaderWith256CharacterIdentifier',
-      fShaderSuccess: true,
-      linkSuccess: true,
-      passMsg: 'shader that uses 256 character identifier should succeed',
-    },
+    //{ vShaderId: 'vshader',
+    //  vShaderSuccess: true,
+    //  fShaderId: 'fshaderWith256CharacterIdentifier',
+    //  fShaderSuccess: true,
+    //  linkSuccess: true,
+    //  passMsg: 'shader that uses 256 character identifier should succeed',
+    //},
     { vShaderId: 'vshader',
       vShaderSuccess: true,
       fShaderId: 'fshaderWithLongLine',
       fShaderSuccess: true,
       fShaderPrep: function(str) {
         function expand(str, re, replacement, count) {
           for (var ii = 0; ii < count; ++ii) {
             str = str.replace(re, replacement);
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -8295,18 +8295,20 @@ nsDocShell::InternalLoad(nsIURI * aURI,
             // Save the current URI; we need it if we fire a hashchange later.
             nsCOMPtr<nsIURI> oldURI = mCurrentURI;
 
             // Save the position of the scrollers.
             nscoord cx = 0, cy = 0;
             GetCurScrollPos(ScrollOrientation_X, &cx);
             GetCurScrollPos(ScrollOrientation_Y, &cy);
 
-            // We scroll the window precisely when we fire a hashchange event.
-            if (doHashchange) {
+            // We scroll whenever we're not doing a history load.  Note that
+            // sometimes we might scroll even if we don't fire a hashchange
+            // event!  See bug 653741.
+            if (!aSHEntry) {
                 // Take the '#' off the hashes before passing them to
                 // ScrollToAnchor.
                 nsDependentCSubstring curHashName(curHash, 1);
                 nsDependentCSubstring newHashName(newHash, 1);
                 rv = ScrollToAnchor(curHashName, newHashName, aLoadType);
                 NS_ENSURE_SUCCESS(rv, rv);
             }
 
--- a/docshell/test/Makefile.in
+++ b/docshell/test/Makefile.in
@@ -96,16 +96,18 @@ include $(topsrcdir)/config/rules.mk
 		file_bug590573_2.html \
 		test_bug598895.html \
 		test_bug634834.html \
 		file_bug634834.html \
 		test_bug637644.html \
 		test_bug640387_1.html \
 		test_bug640387_2.html \
 		file_bug640387.html \
+		test_bug653741.html \
+		file_bug653741.html \
 		test_framedhistoryframes.html \
 		test_windowedhistoryframes.html \
 		historyframes.html \
 		$(NULL)
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
 _TEST_FILES += \
 		test_bug511449.html \
new file mode 100644
--- /dev/null
+++ b/docshell/test/file_bug653741.html
@@ -0,0 +1,13 @@
+<html>
+<body onload='(parent || opener).childLoad()'>
+
+<div style='height:500px; background:yellow'>
+<a id='#top'>Top of the page</a>
+</div>
+
+<div id='bottom'>
+<a id='#bottom'>Bottom of the page</a>
+</div>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/docshell/test/test_bug653741.html
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=653741
+-->
+<head>
+  <title>Test for Bug 653741</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=653741">Mozilla Bug 653741</a>
+
+<script type="application/javascript;version=1.7">
+
+/** Test for Bug 653741 **/
+SimpleTest.waitForExplicitFinish();
+
+function childLoad() {
+  // Spin the event loop so we leave the onload handler.
+  SimpleTest.executeSoon(childLoad2);
+}
+
+function childLoad2() {
+  let cw = $('iframe').contentWindow;
+  
+  // Save the Y offset.  For sanity's sake, make sure it's not 0, because we
+  // should be at the bottom of the page!
+  let origYOffset = cw.pageYOffset;
+  ok(origYOffset != 0, 'Original Y offset is not 0.');
+
+  // Scroll the iframe to the top, then navigate to #bottom again.
+  cw.scrollTo(0, 0);
+
+  // Our current location is #bottom, so this should scroll us down to the
+  // bottom again.
+  cw.location = cw.location + '';
+
+  is(cw.pageYOffset, origYOffset, 'Correct offset after reloading page.');
+  SimpleTest.finish();
+}
+
+</script>
+
+<iframe height='100px' id='iframe' src='file_bug653741.html#bottom'></iframe>
+
+</body>
+</html>
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -862,16 +862,17 @@ ContentParent::RecvSetURITitle(const IPC
       history->SetURITitle(ourURI, title);
     }
     return true;
 }
 
 bool
 ContentParent::RecvShowFilePicker(const PRInt16& mode,
                                   const PRInt16& selectedType,
+                                  const PRBool& addToRecentDocs,
                                   const nsString& title,
                                   const nsString& defaultFile,
                                   const nsString& defaultExtension,
                                   const InfallibleTArray<nsString>& filters,
                                   const InfallibleTArray<nsString>& filterNames,
                                   InfallibleTArray<nsString>* files,
                                   PRInt16* retValue,
                                   nsresult* result)
@@ -887,17 +888,19 @@ ContentParent::RecvShowFilePicker(const 
     nsCOMPtr<nsIWindowWatcher> ww = do_GetService(NS_WINDOWWATCHER_CONTRACTID);
     nsCOMPtr<nsIDOMWindow> window;
     ww->GetActiveWindow(getter_AddRefs(window));
 
     // initialize the "real" picker with all data given
     *result = filePicker->Init(window, title, mode);
     if (NS_FAILED(*result))
         return true;
-    
+
+    filePicker->SetAddToRecentDocs(addToRecentDocs);
+
     PRUint32 count = filters.Length();
     for (PRUint32 i = 0; i < count; ++i) {
         filePicker->AppendFilter(filterNames[i], filters[i]);
     }
 
     filePicker->SetDefaultString(defaultFile);
     filePicker->SetDefaultExtension(defaultExtension);
     filePicker->SetFilterIndex(selectedType);
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -173,16 +173,17 @@ private:
                               const IPC::URI& referrer,
                               const PRUint32& flags);
 
     virtual bool RecvSetURITitle(const IPC::URI& uri,
                                  const nsString& title);
     
     virtual bool RecvShowFilePicker(const PRInt16& mode,
                                     const PRInt16& selectedType,
+                                    const PRBool& addToRecentDocs,
                                     const nsString& title,
                                     const nsString& defaultFile,
                                     const nsString& defaultExtension,
                                     const InfallibleTArray<nsString>& filters,
                                     const InfallibleTArray<nsString>& filterNames,
                                     InfallibleTArray<nsString>* files,
                                     PRInt16* retValue,
                                     nsresult* result);
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -139,17 +139,17 @@ parent:
 
     // Services remoting
 
     async StartVisitedQuery(URI uri);
     async VisitURI(URI uri, URI referrer, PRUint32 flags);
     async SetURITitle(URI uri, nsString title);
     
     // filepicker remoting
-    sync ShowFilePicker(PRInt16 mode, PRInt16 selectedType, 
+    sync ShowFilePicker(PRInt16 mode, PRInt16 selectedType, PRBool addToRecentDocs,
                         nsString title, nsString defaultFile, nsString defaultExtension,
                         nsString[] filters, nsString[] filterNames)
         returns (nsString[] files, PRInt16 retValue, nsresult result);
 
     async LoadURIExternal(URI uri);
 
     // PrefService message
     sync ReadPrefsArray() returns (PrefTuple[] retValue);
--- a/gfx/angle/CONTRIBUTORS
+++ b/gfx/angle/CONTRIBUTORS
@@ -9,24 +9,29 @@
 TransGaming Inc.
  Nicolas Capens
  Daniel Koch
  Andrew Lewycky
  Gavriel State
  Shannon Woods
 
 Google Inc.
+ John Bauman
  Henry Bridge
  N. Duca
  Vangelis Kokkevis
  Alok Priyadarshi
  Alastair Patrick
- Kenneth Russel
+ Kenneth Russell
  Adrienne Walker
+ Ben Vanik
 
 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
--- a/gfx/angle/Makefile.in
+++ b/gfx/angle/Makefile.in
@@ -76,16 +76,18 @@ CPPSRCS = \
         RemoveTree.cpp \
         ShaderLang.cpp \
         SymbolTable.cpp \
 	VariableInfo.cpp \
 	compilerdebug.cpp \
 	ossource_nspr.cpp \
 	util.cpp \
 	ValidateLimitations.cpp \
+	ForLoopUnroll.cpp \
+	MapLongVariableNames.cpp \
 	$(NULL)
 
 # flex/yacc generated files
 CPPSRCS += \
 	glslang_lex.cpp \
 	glslang_tab.cpp \
 	$(NULL)
 
--- a/gfx/angle/README.mozilla
+++ b/gfx/angle/README.mozilla
@@ -1,24 +1,25 @@
 This is the ANGLE project, from http://code.google.com/p/angleproject/.
 
-Current revision: r550
+Current revision: r653
 
-Applied local patches:
-    angle-shared.patch - add declspec dllexport/dllimport support on win32
+== Applied local patches ==
 
-    angle-fixes.patch - fix angle issues 51 & 52
+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-makefiles.patch - Mozilla Makefiles for ANGLE
 
-    angle-nspr-misc.patch - don't bother with ANGLE_OS detection with NSPR
+== How to update this ANGLE copy ==
 
-    angle-pbuffers.patch - add pbuffer support to ANGLE, and d3d texture handle query (angle issue 91)
+1. Unapply patches
+2. Apply diff with new ANGLE version
+3. Reapply patches. Check for newly created/deleted files.
+4. For each file creation/deletetion recorded in step 3, update our makefiles (angle-makefiles.patch) accordingly
 
 == Visual Studio Solution Files ==
 
-The VS solution/project files that are used to build ANGLE are built
-with VS2008 in upstream ANGLE.  Because our build machines use VS2005,
-they need to be downgraded using
-http://www.emmet-gray.com/Articles/ProjectConverter.htm before being
-checked in with an ANGLE update.
+Ignore these. We don't use them anymore. We use custom Makefiles (see angle-makefiles.patch)
 
-== Regenerating Parser ==
+== Generated parser code==
 
-The parser is now generated and included in the ANGLE svn repo.
+Don't bother about that anymore. The parser is now generated and included in the ANGLE svn repo.
deleted file mode 100644
--- a/gfx/angle/angle-fixes.patch
+++ /dev/null
@@ -1,153 +0,0 @@
-# HG changeset patch
-# Parent 50279bda70bb802be20e508ef1f2d7deebf9bc64
-diff --git a/gfx/angle/src/libGLESv2/Renderbuffer.cpp b/gfx/angle/src/libGLESv2/Renderbuffer.cpp
---- a/gfx/angle/src/libGLESv2/Renderbuffer.cpp
-+++ b/gfx/angle/src/libGLESv2/Renderbuffer.cpp
-@@ -241,61 +241,61 @@ Colorbuffer::~Colorbuffer()
-     }
- }
- 
- bool Colorbuffer::isColorbuffer() const
- {
-     return true;
- }
- 
--GLuint Colorbuffer::getRedSize() const
-+GLuint Colorbuffer::getRedSize()
- {
--    if (mRenderTarget)
-+    if (getRenderTarget())
-     {
-         D3DSURFACE_DESC description;
--        mRenderTarget->GetDesc(&description);
-+        getRenderTarget()->GetDesc(&description);
- 
-         return es2dx::GetRedSize(description.Format);
-     }
- 
-     return 0;
- }
- 
--GLuint Colorbuffer::getGreenSize() const
-+GLuint Colorbuffer::getGreenSize()
- {
--    if (mRenderTarget)
-+    if (getRenderTarget())
-     {
-         D3DSURFACE_DESC description;
--        mRenderTarget->GetDesc(&description);
-+        getRenderTarget()->GetDesc(&description);
- 
-         return es2dx::GetGreenSize(description.Format);
-     }
- 
-     return 0;
- }
- 
--GLuint Colorbuffer::getBlueSize() const
-+GLuint Colorbuffer::getBlueSize()
- {
--    if (mRenderTarget)
-+    if (getRenderTarget())
-     {
-         D3DSURFACE_DESC description;
--        mRenderTarget->GetDesc(&description);
-+        getRenderTarget()->GetDesc(&description);
- 
-         return es2dx::GetBlueSize(description.Format);
-     }
- 
-     return 0;
- }
- 
--GLuint Colorbuffer::getAlphaSize() const
-+GLuint Colorbuffer::getAlphaSize()
- {
--    if (mRenderTarget)
-+    if (getRenderTarget())
-     {
-         D3DSURFACE_DESC description;
--        mRenderTarget->GetDesc(&description);
-+        getRenderTarget()->GetDesc(&description);
- 
-         return es2dx::GetAlphaSize(description.Format);
-     }
- 
-     return 0;
- }
- 
- IDirect3DSurface9 *Colorbuffer::getRenderTarget()
-diff --git a/gfx/angle/src/libGLESv2/Renderbuffer.h b/gfx/angle/src/libGLESv2/Renderbuffer.h
---- a/gfx/angle/src/libGLESv2/Renderbuffer.h
-+++ b/gfx/angle/src/libGLESv2/Renderbuffer.h
-@@ -104,20 +104,20 @@ class Colorbuffer : public RenderbufferS
-     explicit Colorbuffer(IDirect3DSurface9 *renderTarget);
-     explicit Colorbuffer(const Texture* texture);
-     Colorbuffer(int width, int height, GLenum format, GLsizei samples);
- 
-     ~Colorbuffer();
- 
-     bool isColorbuffer() const;
- 
--    GLuint getRedSize() const;
--    GLuint getGreenSize() const;
--    GLuint getBlueSize() const;
--    GLuint getAlphaSize() const;
-+    GLuint getRedSize();
-+    GLuint getGreenSize();
-+    GLuint getBlueSize();
-+    GLuint getAlphaSize();
- 
-     IDirect3DSurface9 *getRenderTarget();
- 
-   protected:
-     IDirect3DSurface9 *mRenderTarget;
- 
-   private:
-     DISALLOW_COPY_AND_ASSIGN(Colorbuffer);
-diff --git a/gfx/angle/src/libGLESv2/Texture.cpp b/gfx/angle/src/libGLESv2/Texture.cpp
---- a/gfx/angle/src/libGLESv2/Texture.cpp
-+++ b/gfx/angle/src/libGLESv2/Texture.cpp
-@@ -1313,16 +1313,19 @@ bool Texture2D::redefineTexture(GLint le
-             mTexture = NULL;
-             dropTexture();
-         }
- 
-         mWidth = width << level;
-         mHeight = height << level;
-         mImageArray[0].format = internalFormat;
-         mType = type;
-+
-+        if (mColorbufferProxy.get())
-+            mColorbufferProxy->setStorage(new TextureColorbufferProxy(this, GL_TEXTURE_2D));
-     }
- 
-     return !textureOkay;
- }
- 
- void Texture2D::setImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
- {
-     redefineTexture(level, internalFormat, width, height, type);
-@@ -2210,16 +2213,22 @@ bool TextureCubeMap::redefineTexture(GLi
-         }
- 
-         mWidth = width << level;
-         mImageArray[0][0].width = width << level;
-         mHeight = width << level;
-         mImageArray[0][0].height = width << level;
- 
-         mImageArray[0][0].format = internalFormat;
-+
-+        for (int i = 0; i < 6; i++)
-+        {
-+            if (mFaceProxies[i].get())
-+                mFaceProxies[i]->setStorage(new TextureColorbufferProxy(this, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i));
-+        }
-     }
- 
-     return !textureOkay;
- }
- 
- void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
- {
-     IDirect3DSurface9 *renderTarget = source->getRenderTarget();
new file mode 100644
--- /dev/null
+++ b/gfx/angle/angle-makefiles.patch
@@ -0,0 +1,466 @@
+# HG changeset patch
+# Parent 855fadd845692a09149ece53933c65113e05bb4f
+
+diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
+--- a/gfx/angle/Makefile.in
++++ b/gfx/angle/Makefile.in
+@@ -76,16 +76,18 @@ CPPSRCS = \
+         RemoveTree.cpp \
+         ShaderLang.cpp \
+         SymbolTable.cpp \
+ 	VariableInfo.cpp \
+ 	compilerdebug.cpp \
+ 	ossource_nspr.cpp \
+ 	util.cpp \
+ 	ValidateLimitations.cpp \
++	ForLoopUnroll.cpp \
++	MapLongVariableNames.cpp \
+ 	$(NULL)
+ 
+ # flex/yacc generated files
+ CPPSRCS += \
+ 	glslang_lex.cpp \
+ 	glslang_tab.cpp \
+ 	$(NULL)
+ 
+@@ -101,16 +103,17 @@ CPPSRCS += \
+ # can be selected.
+ 
+ ## HLSL translator backend
+ ##CPPSRCS += \
+ ##	CodeGenHLSL.cpp \
+ ##	OutputHLSL.cpp \
+ ##	TranslatorHLSL.cpp \
+ ##	UnfoldSelect.cpp \
++##	SearchSymbol.cpp \
+ ##	$(NULL)
+ 
+ CSRCS   = \
+         atom.c \
+         cpp.c \
+         cppstruct.c \
+         memory.c \
+         scanner.c \
+@@ -119,77 +122,29 @@ CSRCS   = \
+ 	$(NULL)
+ 
+ DEFINES += -DANGLE_USE_NSPR -DANGLE_BUILD
+ 
+ ifndef MOZ_ENABLE_LIBXUL
+ EXTRA_DSO_LDOPTS = $(MOZ_COMPONENT_LIBS)
+ endif
+ 
++# ANGLE only on Win32 for now, the solution isn't set up
++# for 64-bit yet. This is handled by MOZ_ANGLE which the configure script
++# leaves undefined in the 64-bit case.
++ifdef MOZ_ANGLE
++
++# libEGL depends on (links against!) libGLESv2!
++DIRS = src/libGLESv2 src/libEGL
++
++libs::
++	expand "$(MOZ_D3DX9_CAB)" -F:$(MOZ_D3DX9_DLL) "$(DIST)/bin"
++	expand "$(MOZ_D3DCOMPILER_CAB)" -F:$(MOZ_D3DCOMPILER_DLL) "$(DIST)/bin"
++
++endif
++
+ include $(topsrcdir)/config/rules.mk
+ 
+ # We have to filter out -pedantic, because of
+ # comma-at-end-of-enumerator list failures.  We can try to get this fixed
+ # upstream at some point.
+ CXXFLAGS := $(filter-out -pedantic,$(CXXFLAGS))
+ CFLAGS := $(filter-out -pedantic,$(CFLAGS))
+-
+-# ANGLE only on Win32 for now, the solution isn't set up
+-# for 64-bit yet. This is handled by MOZ_ANGLE which the configure script
+-# leaves undefined in the 64-bit case.
+-ifdef MOZ_ANGLE
+-ifdef MOZ_DEBUG
+-ANGLE_DIR = Debug
+-else
+-ANGLE_DIR = Release
+-endif
+-
+-ifdef MOZ_DIRECTX_SDK_PATH
+-# export is needed for INCLUDE and LIB because devenv //useenv will read these env vars
+-export INCLUDE := $(INCLUDE);$(MOZ_DIRECTX_SDK_PATH)\include
+-export LIB := $(LIB);$(MOZ_DIRECTX_SDK_PATH)\lib\$(MOZ_DIRECTX_SDK_CPU_SUFFIX)
+-endif
+-
+-ANGLE_DEP_PATTERNS = \
+-	src/common/*.cpp src/common/*.h \
+-	src/compiler/*.cpp src/compiler/*.h \
+-	src/compiler/preprocessor/*.cpp src/compiler/preprocessor/*.h \
+-	src/libEGL/*.cpp src/libEGL/*.h \
+-	src/libGLESv2/*.cpp src/libGLESv2/*.h \
+-	$(NULL)
+-
+-ANGLE_DEPS = $(filter-out Gen_glslang.cpp Gen_glslang_tab.cpp glslang_tab.h,$(wildcard $(ANGLE_DEP_PATTERNS)))
+-
+-libs:: libGLESv2.dll libEGL.dll
+-	$(INSTALL) $(IFLAGS2) libGLESv2.dll libEGL.dll $(MOZ_D3DX9_DLL) $(MOZ_D3DCOMPILER_DLL) $(DIST)/bin
+-
+-# we don't want this to attempt to parallel-build these dlls;
+-# building one will build both.
+-libGLESv2.dll: libEGL.dll
+-
+-libEGL.dll: $(GLOBAL_DEPS) $(ANGLE_DEPS)
+-	@(echo "=== Building ANGLE via devenv.exe ===" \
+-	&& rm -rf angle-build && mkdir angle-build \
+-	&& cp -r $(srcdir)/src $(srcdir)/include angle-build \
+-	&& cd angle-build/src \
+-	&& echo "Upgrading solution..." \
+-	&& devenv angle.sln //upgrade \
+-	&& echo "Tweaking project files to use ASLR and DEP..." \
+-	&& ( find . -name '*proj' | xargs \
+-	     perl -i.bak -p \
+-	          -e 'BEGIN{undef $/;} s/<RandomizedBaseAddress>([^<^>])*<\/RandomizedBaseAddress>/<RandomizedBaseAddress>true<\/RandomizedBaseAddress>/sgmi;' \
+-	          -e 'BEGIN{undef $/;} s/<DataExecutionPrevention>([^<^>])*<\/DataExecutionPrevention>/<DataExecutionPrevention>true<\/DataExecutionPrevention>/sgmi;' \
+-		  -e 's/RandomizedBaseAddress\=\"0\"/RandomizedBaseAddress\=\"1\"/g;' \
+-		  -e 's/DataExecutionPrevention\=\"0\"/DataExecutionPrevention\=\"1\"/g;' \
+-	   ) \
+-	&& echo "Building solution, target $(ANGLE_DIR)|Win32..." \
+-	&& ( devenv angle.sln //useenv //build "$(ANGLE_DIR)|Win32" //out ../../angle-build-log.txt \
+-	       || (cat ../../angle-build-log.txt && exit 1) \
+-	   ) \
+-	&& echo "Copying dlls..." \
+-	&& cp $(ANGLE_DIR)/*.dll ../.. \
+-	&& cd ../.. \
+-	&& echo "Extracting dlls from cab file..." \
+-	&& expand "$(MOZ_D3DX9_CAB)" . -F:$(MOZ_D3DX9_DLL) \
+-	&& expand "$(MOZ_D3DCOMPILER_CAB)" . -F:$(MOZ_D3DCOMPILER_DLL) \
+-	)
+-
+-endif
+diff --git a/gfx/angle/src/libEGL/Makefile.in b/gfx/angle/src/libEGL/Makefile.in
+new file mode 100644
+--- /dev/null
++++ b/gfx/angle/src/libEGL/Makefile.in
+@@ -0,0 +1,142 @@
++# 
++# ***** 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 gecko.
++#
++# The Initial Developer of the Original Code is Mozilla Foundation.
++# Portions created by the Initial Developer are Copyright (C) 2011
++# the Initial Developer. All Rights Reserved.
++#
++# Contributor(s):
++#
++# 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 *****
++
++DEPTH    = ../../../..
++topsrcdir  = @top_srcdir@
++srcdir    = @srcdir@
++VPATH    = @srcdir@
++
++include $(DEPTH)/config/autoconf.mk
++
++MODULE = libegl
++# On Windows, we don't automatically get "lib" prepended, but we need it.
++LIBRARY_NAME = libEGL
++MODULE_NAME = libegl
++FORCE_SHARED_LIB=1
++
++# ANGLE uses the STL, so we can't use our derpy STL wrappers.
++STL_FLAGS=
++
++# ANGLE uses exceptions internally, so we need to have exception handling
++# support
++ENABLE_CXX_EXCEPTIONS=1
++
++# Since we're building off in our own world, we don't want to have
++# mozilla-config.h and -DMOZILLA_CLIENT automatically included and defined, so
++# we just overwrite OS_COMPILE_C(XX)FLAGS.
++OS_COMPILE_CFLAGS = $(OS_CPPFLAGS)
++OS_COMPILE_CXXFLAGS = $(OS_CPPFLAGS)
++
++LOCAL_INCLUDES += -I$(srcdir)/../../include -I$(srcdir)/.. -I"$(DXSDK_DIR)/include"
++
++VPATH += $(srcdir)/.. \
++  $(srcdir)/../compiler \
++  $(srcdir)/../compiler/preprocessor \
++  $(srcdir)/../common \
++  $(NULL)
++
++# Translator/compiler first
++
++CPPSRCS = \
++  Compiler.cpp \
++  InfoSink.cpp \
++  Initialize.cpp \
++  InitializeDll.cpp \
++  Intermediate.cpp \
++  intermOut.cpp \
++  IntermTraverse.cpp \
++  MozAngleLink.cpp \
++  parseConst.cpp \
++  ParseHelper.cpp \
++  PoolAlloc.cpp \
++  QualifierAlive.cpp \
++  RemoveTree.cpp \
++  ShaderLang.cpp \
++  SymbolTable.cpp \
++  VariableInfo.cpp \
++  compilerdebug.cpp \
++  ossource_win.cpp \
++  util.cpp \
++  ValidateLimitations.cpp \
++  ForLoopUnroll.cpp \
++  MapLongVariableNames.cpp \
++  $(NULL)
++
++# flex/yacc generated files
++CPPSRCS += \
++  glslang_lex.cpp \
++  glslang_tab.cpp \
++  $(NULL)
++
++# HLSL translator backend
++CPPSRCS += \
++  CodeGenHLSL.cpp \
++  OutputHLSL.cpp \
++  TranslatorHLSL.cpp \
++  UnfoldSelect.cpp \
++  SearchSymbol.cpp \
++  $(NULL)
++
++CSRCS   = \
++  atom.c \
++  cpp.c \
++  cppstruct.c \
++  memory.c \
++  scanner.c \
++  symbols.c \
++  tokens.c \
++  $(NULL)
++
++DEFINES += -DANGLE_BUILD -DNOMINMAX -DLIBEGL_EXPORTS -D_CRT_SECURE_NO_DEPRECATE
++
++ifndef MOZ_DEBUG
++DEFINES += -D_SECURE_SCL=0
++endif
++
++CPPSRCS += \
++  debug.cpp \
++  Config.cpp \
++  Display.cpp \
++  libEGL.cpp \
++  main.cpp \
++  Surface.cpp \
++  $(NULL)
++
++DEFFILE = $(srcdir)/libEGL.def
++
++include $(topsrcdir)/config/rules.mk
++
++EXTRA_DSO_LDOPTS = "$(MOZ_DIRECTX_SDK_PATH)/lib/x86/d3d9.lib" "$(MOZ_DIRECTX_SDK_PATH)/lib/x86/dxguid.lib" $(DIST)/lib/libGLESv2.lib
+diff --git a/gfx/angle/src/libGLESv2/Makefile.in b/gfx/angle/src/libGLESv2/Makefile.in
+new file mode 100644
+--- /dev/null
++++ b/gfx/angle/src/libGLESv2/Makefile.in
+@@ -0,0 +1,157 @@
++# 
++# ***** 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 gecko.
++#
++# The Initial Developer of the Original Code is Mozilla Foundation.
++# Portions created by the Initial Developer are Copyright (C) 2011
++# the Initial Developer. All Rights Reserved.
++#
++# Contributor(s):
++#
++# 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 *****
++
++DEPTH		= ../../../..
++topsrcdir	= @top_srcdir@
++srcdir		= @srcdir@
++VPATH		= @srcdir@
++
++include $(DEPTH)/config/autoconf.mk
++
++MODULE = libglesv2
++# On Windows, we don't automatically get "lib" prepended, but we need it.
++LIBRARY_NAME = libGLESv2
++MODULE_NAME = libglesv2
++FORCE_SHARED_LIB=1
++
++# ANGLE uses the STL, so we can't use our derpy STL wrappers.
++STL_FLAGS=
++
++# ANGLE uses exceptions internally, so we need to have exception handling
++# support
++ENABLE_CXX_EXCEPTIONS=1
++
++# Since we're building off in our own world, we don't want to have
++# mozilla-config.h and -DMOZILLA_CLIENT automatically included and defined, so
++# we just overwrite OS_COMPILE_C(XX)FLAGS.
++OS_COMPILE_CFLAGS = $(OS_CPPFLAGS)
++OS_COMPILE_CXXFLAGS = $(OS_CPPFLAGS)
++
++LOCAL_INCLUDES = -I$(srcdir)/../../include -I$(srcdir)/.. -I"$(DXSDK_DIR)/include"
++
++VPATH += $(srcdir)/..
++VPATH += $(srcdir)/../compiler
++VPATH += $(srcdir)/../compiler/preprocessor
++VPATH += $(srcdir)/../common
++VPATH += $(srcdir)/geometry
++
++# Translator/compiler first
++
++CPPSRCS = \
++	Compiler.cpp \
++        InfoSink.cpp \
++        Initialize.cpp \
++        InitializeDll.cpp \
++        Intermediate.cpp \
++        intermOut.cpp \
++        IntermTraverse.cpp \
++        MozAngleLink.cpp \
++        parseConst.cpp \
++        ParseHelper.cpp \
++        PoolAlloc.cpp \
++        QualifierAlive.cpp \
++        RemoveTree.cpp \
++        ShaderLang.cpp \
++        SymbolTable.cpp \
++        VariableInfo.cpp \
++        compilerdebug.cpp \
++        ossource_win.cpp \
++        util.cpp \
++        ValidateLimitations.cpp \
++	ForLoopUnroll.cpp \
++	MapLongVariableNames.cpp \
++	$(NULL)
++
++# flex/yacc generated files
++CPPSRCS += \
++	glslang_lex.cpp \
++	glslang_tab.cpp \
++	$(NULL)
++
++# HLSL translator backend
++CPPSRCS += \
++	CodeGenHLSL.cpp \
++	OutputHLSL.cpp \
++	TranslatorHLSL.cpp \
++	UnfoldSelect.cpp \
++	SearchSymbol.cpp \
++	$(NULL)
++
++CSRCS   = \
++        atom.c \
++        cpp.c \
++        cppstruct.c \
++        memory.c \
++        scanner.c \
++        symbols.c \
++        tokens.c \
++	$(NULL)
++
++DEFINES += -DANGLE_BUILD -DNOMINMAX -DLIBGLESV2_EXPORTS -D_CRT_SECURE_NO_DEPRECATE
++
++ifndef MOZ_DEBUG
++DEFINES += -D_SECURE_SCL=0
++endif
++
++CPPSRCS	+= \
++	debug.cpp \
++	IndexDataManager.cpp \
++	VertexDataManager.cpp \
++	Blit.cpp \
++	Buffer.cpp \
++	Context.cpp \
++	Fence.cpp \
++	Framebuffer.cpp \
++	libGLESv2.cpp \
++	main.cpp \
++	Program.cpp \
++	RefCountObject.cpp \
++	Renderbuffer.cpp \
++	ResourceManager.cpp \
++	Shader.cpp \
++	Texture.cpp \
++	utilities.cpp \
++	HandleAllocator.cpp \
++	IndexDataManager.cpp \
++	VertexDataManager.cpp \
++	$(NULL)
++
++DEFFILE = $(srcdir)/libGLESv2.def
++
++
++include $(topsrcdir)/config/rules.mk
++
++EXTRA_DSO_LDOPTS = "$(MOZ_DIRECTX_SDK_PATH)/lib/x86/d3d9.lib" "$(MOZ_DIRECTX_SDK_PATH)/lib/x86/d3dx9.lib"
+diff --git a/toolkit/toolkit-makefiles.sh b/toolkit/toolkit-makefiles.sh
+--- a/toolkit/toolkit-makefiles.sh
++++ b/toolkit/toolkit-makefiles.sh
+@@ -123,16 +123,18 @@ MAKEFILES_gfx="
+   gfx/Makefile
+   gfx/ycbcr/Makefile
+   gfx/layers/Makefile
+   gfx/src/Makefile
+   gfx/tests/Makefile
+   gfx/thebes/Makefile
+   gfx/qcms/Makefile
+   gfx/angle/Makefile
++  gfx/angle/src/libGLESv2/Makefile
++  gfx/angle/src/libEGL/Makefile
+ "
+ 
+ MAKEFILES_htmlparser="
+   parser/htmlparser/Makefile
+   parser/htmlparser/public/Makefile
+   parser/htmlparser/src/Makefile
+   parser/htmlparser/tests/Makefile
+   parser/htmlparser/tests/grabpage/Makefile
--- a/gfx/angle/angle-nspr-misc.patch
+++ b/gfx/angle/angle-nspr-misc.patch
@@ -1,10 +1,10 @@
 # HG changeset patch
-# Parent 3f4e2a35c49bb865018798a76b62c169d8e3537b
+# Parent 3e177ced3662763eae55f4b741258298609e99aa
 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
 @@ -7,17 +7,19 @@
  #ifndef __OSINCLUDE_H
  #define __OSINCLUDE_H
  
  //
deleted file mode 100644
--- a/gfx/angle/angle-pbuffers.patch
+++ /dev/null
@@ -1,860 +0,0 @@
-# HG changeset patch
-# Parent f0b9a118e816430191f013f327a19aff57cfb136
-try: -b do -p win32 -u all -t none
-repair ANGLE
-
-diff --git a/gfx/angle/include/EGL/eglext.h b/gfx/angle/include/EGL/eglext.h
---- a/gfx/angle/include/EGL/eglext.h
-+++ b/gfx/angle/include/EGL/eglext.h
-@@ -210,13 +210,26 @@ EGLBoolean eglGetSyncAttribNV (EGLSyncNV
- 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
- 
-+#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_share_handle
-+#define EGL_ANGLE_surface_d3d_share_handle
-+#define EGL_D3D_TEXTURE_SHARE_HANDLE_ANGLE 0x3200
-+#endif
-+
- #ifdef __cplusplus
- }
- #endif
- 
- #endif
-diff --git a/gfx/angle/src/libEGL/Config.cpp b/gfx/angle/src/libEGL/Config.cpp
---- a/gfx/angle/src/libEGL/Config.cpp
-+++ b/gfx/angle/src/libEGL/Config.cpp
-@@ -14,20 +14,20 @@
- #include <vector>
- 
- #include "common/debug.h"
- 
- using namespace std;
- 
- namespace egl
- {
--Config::Config(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample)
-+Config::Config(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample, EGLint texWidth, EGLint texHeight)
-     : mDisplayMode(displayMode), mRenderTargetFormat(renderTargetFormat), mDepthStencilFormat(depthStencilFormat), mMultiSample(multiSample)
- {
--    set(displayMode, minInterval, maxInterval, renderTargetFormat, depthStencilFormat, multiSample);
-+    set(displayMode, minInterval, maxInterval, renderTargetFormat, depthStencilFormat, multiSample, texWidth, texHeight);
- }
- 
- void Config::setDefaults()
- {
-     mBufferSize = 0;
-     mRedSize = 0;
-     mGreenSize = 0;
-     mBlueSize = 0;
-@@ -57,17 +57,17 @@ void Config::setDefaults()
-     mStencilSize = 0;
-     mSurfaceType = EGL_WINDOW_BIT;
-     mTransparentType = EGL_NONE;
-     mTransparentRedValue = EGL_DONT_CARE;
-     mTransparentGreenValue = EGL_DONT_CARE;
-     mTransparentBlueValue = EGL_DONT_CARE;
- }
- 
--void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample)
-+void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample, EGLint texWidth, EGLint texHeight)
- {
-     switch (renderTargetFormat)
-     {
-       case D3DFMT_A1R5G5B5:
-         mBufferSize = 16;
-         mRedSize = 5;
-         mGreenSize = 5;
-         mBlueSize = 5;
-@@ -153,19 +153,19 @@ void Config::set(D3DDISPLAYMODE displayM
- //      mStencilSize = 8;
- //      break;
-       default:
-         UNREACHABLE();
-     }
- 
-     mLevel = 0;
-     mMatchNativePixmap = EGL_NONE;
--    mMaxPBufferWidth = 0;
--    mMaxPBufferHeight = 0;
--    mMaxPBufferPixels = 0;
-+    mMaxPBufferWidth = texWidth;
-+    mMaxPBufferHeight = texHeight;
-+    mMaxPBufferPixels = texWidth*texHeight;
-     mMaxSwapInterval = maxInterval;
-     mMinSwapInterval = minInterval;
-     mNativeRenderable = EGL_FALSE;
-     mNativeVisualID = 0;
-     mNativeVisualType = 0;
-     mRenderableType = EGL_OPENGL_ES2_BIT;
-     mSampleBuffers = multiSample ? 1 : 0;
-     mSamples = multiSample;
-@@ -277,19 +277,19 @@ const EGLint ConfigSet::mSortAttribs[] =
-     EGL_NONE
- };
- 
- ConfigSet::ConfigSet()
-     : mSet(SortConfig(mSortAttribs))
- {
- }
- 
--void ConfigSet::add(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample)
-+void ConfigSet::add(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample, EGLint texWidth, EGLint texHeight)
- {
--    Config config(displayMode, minSwapInterval, maxSwapInterval, renderTargetFormat, depthStencilFormat, multiSample);
-+    Config config(displayMode, minSwapInterval, maxSwapInterval, renderTargetFormat, depthStencilFormat, multiSample, texWidth, texHeight);
- 
-     mSet.insert(config);
- }
- 
- size_t ConfigSet::size() const
- {
-     return mSet.size();
- }
-@@ -332,16 +332,19 @@ bool ConfigSet::getConfigs(EGLConfig *co
-               case EGL_MIN_SWAP_INTERVAL:         match = config->mMinSwapInterval == attribute[1];                 break;
-               case EGL_MAX_SWAP_INTERVAL:         match = config->mMaxSwapInterval == attribute[1];                 break;
-               case EGL_LUMINANCE_SIZE:            match = config->mLuminanceSize >= attribute[1];                   break;
-               case EGL_ALPHA_MASK_SIZE:           match = config->mAlphaMaskSize >= attribute[1];                   break;
-               case EGL_COLOR_BUFFER_TYPE:         match = config->mColorBufferType == attribute[1];                 break;
-               case EGL_RENDERABLE_TYPE:           match = (config->mRenderableType & attribute[1]) == attribute[1]; break;
-               case EGL_MATCH_NATIVE_PIXMAP:       match = false; UNIMPLEMENTED();                                   break;
-               case EGL_CONFORMANT:                match = (config->mConformant & attribute[1]) == attribute[1];     break;
-+              case EGL_MAX_PBUFFER_WIDTH:         match = config->mMaxPBufferWidth >= attribute[1];                 break;
-+              case EGL_MAX_PBUFFER_HEIGHT:        match = config->mMaxPBufferHeight >= attribute[1];                break;
-+              case EGL_MAX_PBUFFER_PIXELS:        match = config->mMaxPBufferPixels >= attribute[1];                break;
-               default:
-                 return false;
-             }
- 
-             if (!match)
-             {
-                 break;
-             }
-diff --git a/gfx/angle/src/libEGL/Config.h b/gfx/angle/src/libEGL/Config.h
---- a/gfx/angle/src/libEGL/Config.h
-+++ b/gfx/angle/src/libEGL/Config.h
-@@ -21,20 +21,20 @@
- 
- namespace egl
- {
- class Display;
- 
- class Config
- {
-   public:
--    Config(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample);
-+    Config(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample, EGLint texWidth, EGLint texHeight);
- 
-     void setDefaults();
--    void set(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample);
-+    void set(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample, EGLint texWidth, EGLint texHeight);
-     EGLConfig getHandle() const;
- 
-     const D3DDISPLAYMODE mDisplayMode;
-     const D3DFORMAT mRenderTargetFormat;
-     const D3DFORMAT mDepthStencilFormat;
-     const EGLint mMultiSample;
- 
-     EGLint mBufferSize;              // Depth of the color buffer
-@@ -94,17 +94,17 @@ class SortConfig
- 
- class ConfigSet
- {
-     friend Display;
- 
-   public:
-     ConfigSet();
- 
--    void add(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample);
-+    void add(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample, EGLint texWidth, EGLint texHeight);
-     size_t size() const;
-     bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig);
-     const egl::Config *get(EGLConfig configHandle);
- 
-   private:
-     DISALLOW_COPY_AND_ASSIGN(ConfigSet);
- 
-     typedef std::set<Config, SortConfig> Set;
-diff --git a/gfx/angle/src/libEGL/Display.cpp b/gfx/angle/src/libEGL/Display.cpp
---- a/gfx/angle/src/libEGL/Display.cpp
-+++ b/gfx/angle/src/libEGL/Display.cpp
-@@ -175,17 +175,18 @@ bool Display::initialize()
-                     if (SUCCEEDED(result))
-                     {
-                         HRESULT result = mD3d9->CheckDepthStencilMatch(mAdapter, mDeviceType, currentDisplayMode.Format, renderTargetFormat, depthStencilFormat);
- 
-                         if (SUCCEEDED(result))
-                         {
-                             // FIXME: enumerate multi-sampling
- 
--                            configSet.add(currentDisplayMode, mMinSwapInterval, mMaxSwapInterval, renderTargetFormat, depthStencilFormat, 0);
-+                            configSet.add(currentDisplayMode, mMinSwapInterval, mMaxSwapInterval, renderTargetFormat, depthStencilFormat, 0,
-+                                          mDeviceCaps.MaxTextureWidth, mDeviceCaps.MaxTextureHeight);
-                         }
-                     }
-                 }
-             }
-         }
- 
-         // Give the sorted configs a unique ID and store them internally
-         EGLint index = 1;
-@@ -317,16 +318,19 @@ bool Display::getConfigAttrib(EGLConfig 
-       case EGL_MIN_SWAP_INTERVAL:         *value = configuration->mMinSwapInterval;        break;
-       case EGL_MAX_SWAP_INTERVAL:         *value = configuration->mMaxSwapInterval;        break;
-       case EGL_LUMINANCE_SIZE:            *value = configuration->mLuminanceSize;          break;
-       case EGL_ALPHA_MASK_SIZE:           *value = configuration->mAlphaMaskSize;          break;
-       case EGL_COLOR_BUFFER_TYPE:         *value = configuration->mColorBufferType;        break;
-       case EGL_RENDERABLE_TYPE:           *value = configuration->mRenderableType;         break;
-       case EGL_MATCH_NATIVE_PIXMAP:       *value = false; UNIMPLEMENTED();                 break;
-       case EGL_CONFORMANT:                *value = configuration->mConformant;             break;
-+      case EGL_MAX_PBUFFER_WIDTH:         *value = configuration->mMaxPBufferWidth;        break;
-+      case EGL_MAX_PBUFFER_HEIGHT:        *value = configuration->mMaxPBufferHeight;       break;
-+      case EGL_MAX_PBUFFER_PIXELS:        *value = configuration->mMaxPBufferPixels;       break;
-       default:
-         return false;
-     }
- 
-     return true;
- }
- 
- bool Display::createDevice()
-@@ -388,16 +392,26 @@ Surface *Display::createWindowSurface(HW
-     const Config *configuration = mConfigSet.get(config);
- 
-     Surface *surface = new Surface(this, configuration, window);
-     mSurfaceSet.insert(surface);
- 
-     return surface;
- }
- 
-+Surface *Display::createOffscreenSurface(int width, int height, EGLConfig config)
-+{
-+    const Config *configuration = mConfigSet.get(config);
-+
-+    Surface *surface = new Surface(this, configuration, width, height);
-+    mSurfaceSet.insert(surface);
-+
-+    return surface;
-+}
-+
- EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *shareContext)
- {
-     if (!mDevice)
-     {
-         if (!createDevice())
-         {
-             return NULL;
-         }
-@@ -641,9 +655,9 @@ D3DPRESENT_PARAMETERS Display::getDefaul
-     presentParameters.MultiSampleQuality = 0;
-     presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
-     presentParameters.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
-     presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
-     presentParameters.Windowed = TRUE;
- 
-     return presentParameters;
- }
--}
-\ No newline at end of file
-+}
-diff --git a/gfx/angle/src/libEGL/Display.h b/gfx/angle/src/libEGL/Display.h
---- a/gfx/angle/src/libEGL/Display.h
-+++ b/gfx/angle/src/libEGL/Display.h
-@@ -38,16 +38,17 @@ class Display
- 
-     virtual void startScene();
-     virtual void endScene();
- 
-     bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig);
-     bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value);
- 
-     egl::Surface *createWindowSurface(HWND window, EGLConfig config);
-+    egl::Surface *createOffscreenSurface(int width, int height, EGLConfig config);
-     EGLContext createContext(EGLConfig configHandle, const gl::Context *shareContext);
- 
-     void destroySurface(egl::Surface *surface);
-     void destroyContext(gl::Context *context);
- 
-     bool isInitialized();
-     bool isValidConfig(EGLConfig config);
-     bool isValidContext(gl::Context *context);
-@@ -63,16 +64,18 @@ class Display
-     virtual bool getCompressedTextureSupport();
-     virtual bool getEventQuerySupport();
-     virtual bool getFloatTextureSupport(bool *filtering, bool *renderable);
-     virtual bool getHalfFloatTextureSupport(bool *filtering, bool *renderable);
-     virtual bool getLuminanceTextureSupport();
-     virtual bool getLuminanceAlphaTextureSupport();
-     virtual D3DPOOL getBufferPool(DWORD usage) const;
- 
-+    bool isD3d9exDevice() { return mD3d9ex != NULL; }
-+
-   private:
-     DISALLOW_COPY_AND_ASSIGN(Display);
- 
-     D3DPRESENT_PARAMETERS getDefaultPresentParameters();
- 
-     const HDC mDc;
- 
-     HMODULE mD3d9Module;
-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
-@@ -20,27 +20,48 @@
- namespace egl
- {
- Surface::Surface(Display *display, const Config *config, HWND window) 
-     : mDisplay(display), mConfig(config), mWindow(window)
- {
-     mSwapChain = NULL;
-     mDepthStencil = NULL;
-     mRenderTarget = NULL;
-+    mOffscreenTexture = NULL;
-+    mShareHandle = NULL;
- 
-     mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING);   // FIXME: Determine actual pixel aspect ratio
-     mRenderBuffer = EGL_BACK_BUFFER;
-     mSwapBehavior = EGL_BUFFER_PRESERVED;
-     mSwapInterval = -1;
-     setSwapInterval(1);
- 
-     subclassWindow();
-     resetSwapChain();
- }
- 
-+Surface::Surface(Display *display, const Config *config, EGLint width, EGLint height)
-+    : mDisplay(display), mWindow(NULL), mConfig(config), mWidth(width), mHeight(height)
-+{
-+    mSwapChain = NULL;
-+    mDepthStencil = NULL;
-+    mRenderTarget = NULL;
-+    mOffscreenTexture = NULL;
-+    mShareHandle = NULL;
-+    mWindowSubclassed = false;
-+
-+    mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING);   // FIXME: Determine actual pixel aspect ratio
-+    mRenderBuffer = EGL_BACK_BUFFER;
-+    mSwapBehavior = EGL_BUFFER_PRESERVED;
-+    mSwapInterval = -1;
-+    setSwapInterval(1);
-+
-+    resetSwapChain(width, height);
-+}
-+
- Surface::~Surface()
- {
-     unsubclassWindow();
-     release();
- }
- 
- void Surface::release()
- {
-@@ -56,20 +77,31 @@ void Surface::release()
-         mDepthStencil = NULL;
-     }
- 
-     if (mRenderTarget)
-     {
-         mRenderTarget->Release();
-         mRenderTarget = NULL;
-     }
-+
-+    if (mOffscreenTexture)
-+    {
-+        mOffscreenTexture->Release();
-+        mOffscreenTexture = NULL;
-+    }
- }
- 
- void Surface::resetSwapChain()
- {
-+    if (!mWindow) {
-+        resetSwapChain(mWidth, mHeight);
-+        return;
-+    }
-+
-     RECT windowRect;
-     if (!GetClientRect(getWindowHandle(), &windowRect))
-     {
-         ASSERT(false);
- 
-         ERR("Could not retrieve the window dimensions");
-         return;
-     }
-@@ -85,40 +117,52 @@ void Surface::resetSwapChain(int backbuf
-     {
-         return;
-     }
- 
-     // Evict all non-render target textures to system memory and release all resources
-     // before reallocating them to free up as much video memory as possible.
-     device->EvictManagedResources();
-     release();
--    
-+
-     D3DPRESENT_PARAMETERS presentParameters = {0};
-+    HRESULT result;
- 
-     presentParameters.AutoDepthStencilFormat = mConfig->mDepthStencilFormat;
-     presentParameters.BackBufferCount = 1;
-     presentParameters.BackBufferFormat = mConfig->mRenderTargetFormat;
-     presentParameters.EnableAutoDepthStencil = FALSE;
-     presentParameters.Flags = 0;
-     presentParameters.hDeviceWindow = getWindowHandle();
-     presentParameters.MultiSampleQuality = 0;                  // FIXME: Unimplemented
-     presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;   // FIXME: Unimplemented
-     presentParameters.PresentationInterval = mPresentInterval;
-     presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
-     presentParameters.Windowed = TRUE;
-     presentParameters.BackBufferWidth = backbufferWidth;
-     presentParameters.BackBufferHeight = backbufferHeight;
- 
--    HRESULT result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain);
-+    if (mWindow)
-+    {
-+        result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain);
-+    } else {
-+        HANDLE *pShareHandle = NULL;
-+        if (mDisplay->isD3d9exDevice()) {
-+            pShareHandle = &mShareHandle;
-+        }
-+
-+        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);
- 
--        ERR("Could not create additional swap chains: %08lX", result);
-+        ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result);
-         release();
-         return error(EGL_BAD_ALLOC);
-     }
- 
-     result = device->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight,
-                                                presentParameters.AutoDepthStencilFormat, presentParameters.MultiSampleType,
-                                                presentParameters.MultiSampleQuality, FALSE, &mDepthStencil, NULL);
- 
-@@ -126,23 +170,27 @@ void Surface::resetSwapChain(int backbuf
-     {
-         ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- 
-         ERR("Could not create depthstencil surface for new swap chain: %08lX", result);
-         release();
-         return error(EGL_BAD_ALLOC);
-     }
- 
--    mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mRenderTarget);
-+    if (mWindow) {
-+        mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mRenderTarget);
-+        InvalidateRect(mWindow, NULL, FALSE);
-+    } else {
-+        mOffscreenTexture->GetSurfaceLevel(0, &mRenderTarget);
-+    }
-+
-     mWidth = presentParameters.BackBufferWidth;
-     mHeight = presentParameters.BackBufferHeight;
- 
-     mPresentIntervalDirty = false;
--
--    InvalidateRect(mWindow, NULL, FALSE);
- }
- 
- HWND Surface::getWindowHandle()
- {
-     return mWindow;
- }
- 
- 
-@@ -157,16 +205,19 @@ static LRESULT CALLBACK SurfaceWindowPro
-       }
-   }
-   WNDPROC prevWndFunc = reinterpret_cast<WNDPROC >(GetProp(hwnd, kParentWndProc));
-   return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam);
- }
- 
- void Surface::subclassWindow()
- {
-+  if (!mWindow)
-+    return;
-+
-   SetLastError(0);
-   LONG oldWndProc = SetWindowLong(mWindow, GWL_WNDPROC, reinterpret_cast<LONG>(SurfaceWindowProc));
-   if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS) {
-     mWindowSubclassed = false;
-     return;
-   }
- 
-   SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
-diff --git a/gfx/angle/src/libEGL/Surface.h b/gfx/angle/src/libEGL/Surface.h
---- a/gfx/angle/src/libEGL/Surface.h
-+++ b/gfx/angle/src/libEGL/Surface.h
-@@ -21,41 +21,47 @@ namespace egl
- {
- class Display;
- class Config;
- 
- class Surface
- {
-   public:
-     Surface(Display *display, const egl::Config *config, HWND window);
-+    Surface(Display *display, const egl::Config *config, EGLint width, EGLint height);
- 
-     ~Surface();
- 
-     void release();
-     void resetSwapChain();
- 
-     HWND getWindowHandle();
-     bool swap();
- 
-     virtual EGLint getWidth() const;
-     virtual EGLint getHeight() const;
- 
-     virtual IDirect3DSurface9 *getRenderTarget();
-     virtual IDirect3DSurface9 *getDepthStencil();
- 
-+    HANDLE getShareHandle() { return mShareHandle; }
-+
-     void setSwapInterval(EGLint interval);
-     bool checkForOutOfDateSwapChain();   // Returns true if swapchain changed due to resize or interval update
- 
- private:
-     DISALLOW_COPY_AND_ASSIGN(Surface);
- 
-     Display *const mDisplay;
-     IDirect3DSwapChain9 *mSwapChain;
-     IDirect3DSurface9 *mDepthStencil;
-     IDirect3DSurface9* mRenderTarget;
-+    IDirect3DTexture9* mOffscreenTexture;
-+
-+    HANDLE mShareHandle;
- 
-     void subclassWindow();
-     void unsubclassWindow();
-     void resetSwapChain(int backbufferWidth, int backbufferHeight);
-     static DWORD convertInterval(EGLint interval);
- 
-     const HWND mWindow;            // Window that the surface is created for.
-     bool mWindowSubclassed;        // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking
-diff --git a/gfx/angle/src/libEGL/libEGL.cpp b/gfx/angle/src/libEGL/libEGL.cpp
---- a/gfx/angle/src/libEGL/libEGL.cpp
-+++ b/gfx/angle/src/libEGL/libEGL.cpp
-@@ -189,17 +189,17 @@ const char *__stdcall eglQueryString(EGL
-             return NULL;
-         }
- 
-         switch (name)
-         {
-           case EGL_CLIENT_APIS:
-             return success("OpenGL_ES");
-           case EGL_EXTENSIONS:
--            return success("");
-+            return success("EGL_ANGLE_query_surface_pointer EGL_ANGLE_surface_d3d_share_handle");
-           case EGL_VENDOR:
-             return success("Google Inc.");
-           case EGL_VERSION:
-             return success("1.4 (ANGLE "VERSION_STRING")");
-         }
- 
-         return error(EGL_BAD_PARAMETER, (const char*)NULL);
-     }
-@@ -386,25 +386,71 @@ EGLSurface __stdcall eglCreateWindowSurf
- EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
- {
-     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)",
-           dpy, config, attrib_list);
- 
-     try
-     {
-         egl::Display *display = static_cast<egl::Display*>(dpy);
-+        EGLint width = 0, height = 0;
- 
-         if (!validate(display, config))
-         {
-             return EGL_NO_SURFACE;
-         }
- 
--        UNIMPLEMENTED();   // FIXME
-+        if (attrib_list)
-+        {
-+            while (*attrib_list != EGL_NONE)
-+            {
-+                switch (attrib_list[0])
-+                {
-+                  case EGL_WIDTH:
-+                    width = attrib_list[1];
-+                    break;
-+                  case EGL_HEIGHT:
-+                    height = attrib_list[1];
-+                    break;
-+                  case EGL_LARGEST_PBUFFER:
-+                    if (attrib_list[1] != EGL_FALSE)
-+                      UNIMPLEMENTED(); // FIXME
-+                    break;
-+                  case EGL_TEXTURE_FORMAT:
-+                  case EGL_TEXTURE_TARGET:
-+                    switch (attrib_list[1])
-+                    {
-+                      case EGL_NO_TEXTURE:
-+                        break;
-+                      default:
-+                        return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-+                    }
-+                    break;
-+                  case EGL_MIPMAP_TEXTURE:
-+                    if (attrib_list[1] != EGL_FALSE)
-+                      return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-+                    break;
-+                  case EGL_VG_COLORSPACE:
-+                    return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
-+                  case EGL_VG_ALPHA_FORMAT:
-+                    return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
-+                  default:
-+                    return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-+                }
- 
--        return success(EGL_NO_DISPLAY);
-+                attrib_list += 2;
-+            }
-+        }
-+
-+        if (width == 0 || height == 0)
-+          return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-+
-+        EGLSurface surface = (EGLSurface)display->createOffscreenSurface(width, height, config);
-+
-+        return success(surface);
-     }
-     catch(std::bad_alloc&)
-     {
-         return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
-     }
- 
-     return EGL_NO_SURFACE;
- }
-@@ -420,17 +466,17 @@ EGLSurface __stdcall eglCreatePixmapSurf
- 
-         if (!validate(display, config))
-         {
-             return EGL_NO_SURFACE;
-         }
- 
-         UNIMPLEMENTED();   // FIXME
- 
--        return success(EGL_NO_DISPLAY);
-+        return success(EGL_NO_SURFACE);
-     }
-     catch(std::bad_alloc&)
-     {
-         return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
-     }
- 
-     return EGL_NO_SURFACE;
- }
-@@ -545,16 +591,56 @@ EGLBoolean __stdcall eglQuerySurface(EGL
-     catch(std::bad_alloc&)
-     {
-         return error(EGL_BAD_ALLOC, EGL_FALSE);
-     }
- 
-     return EGL_FALSE;
- }
- 
-+EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value)
-+{
-+    TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, void **value = 0x%0.8p)",
-+          dpy, surface, attribute, value);
-+
-+    try
-+    {
-+        egl::Display *display = static_cast<egl::Display*>(dpy);
-+
-+        if (!validate(display))
-+        {
-+            return EGL_FALSE;
-+        }
-+
-+        if (surface == EGL_NO_SURFACE)
-+        {
-+            return error(EGL_BAD_SURFACE, EGL_FALSE);
-+        }
-+
-+        egl::Surface *eglSurface = (egl::Surface*)surface;
-+
-+        switch (attribute)
-+        {
-+          case EGL_D3D_TEXTURE_SHARE_HANDLE_ANGLE:
-+            *value = (void*) eglSurface->getShareHandle();
-+            break;
-+          default:
-+            return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
-+        }
-+
-+        return success(EGL_TRUE);
-+    }
-+    catch(std::bad_alloc&)
-+    {
-+        return error(EGL_BAD_ALLOC, EGL_FALSE);
-+    }
-+
-+    return EGL_FALSE;
-+}
-+
- EGLBoolean __stdcall eglBindAPI(EGLenum api)
- {
-     EVENT("(EGLenum api = 0x%X)", api);
- 
-     try
-     {
-         switch (api)
-         {
-@@ -694,19 +780,19 @@ EGLBoolean __stdcall eglBindTexImage(EGL
-     {
-         egl::Display *display = static_cast<egl::Display*>(dpy);
- 
-         if (!validate(display))
-         {
-             return EGL_FALSE;
-         }
- 
--        UNIMPLEMENTED();   // FIXME
-+        // FIXME - need implementation
- 
--        return success(EGL_TRUE);
-+        return success(EGL_FALSE);
-     }
-     catch(std::bad_alloc&)
-     {
-         return error(EGL_BAD_ALLOC, EGL_FALSE);
-     }
- 
-     return EGL_FALSE;
- }
-@@ -719,19 +805,19 @@ EGLBoolean __stdcall eglReleaseTexImage(
-     {
-         egl::Display *display = static_cast<egl::Display*>(dpy);
- 
-         if (!validate(display))
-         {
-             return EGL_FALSE;
-         }
- 
--        UNIMPLEMENTED();   // FIXME
-+        // FIXME - need implementation
- 
--        return success(EGL_TRUE);
-+        return success(EGL_FALSE);
-     }
-     catch(std::bad_alloc&)
-     {
-         return error(EGL_BAD_ALLOC, EGL_FALSE);
-     }
- 
-     return EGL_FALSE;
- }
-@@ -1088,16 +1174,17 @@ __eglMustCastToProperFunctionPointerType
-         struct Extension
-         {
-             const char *name;
-             __eglMustCastToProperFunctionPointerType address;
-         };
- 
-         static const Extension eglExtensions[] =
-         {
-+            {"eglQuerySurfacePointerANGLE", (__eglMustCastToProperFunctionPointerType)eglQuerySurfacePointerANGLE},
-             {"", NULL},
-         };
- 
-         for (int ext = 0; ext < sizeof(eglExtensions) / sizeof(Extension); ext++)
-         {
-             if (strcmp(procname, eglExtensions[ext].name) == 0)
-             {
-                 return (__eglMustCastToProperFunctionPointerType)eglExtensions[ext].address;
-diff --git a/gfx/angle/src/libEGL/main.h b/gfx/angle/src/libEGL/main.h
---- a/gfx/angle/src/libEGL/main.h
-+++ b/gfx/angle/src/libEGL/main.h
-@@ -6,16 +6,17 @@
- 
- // main.h: Management of thread-local data.
- 
- #ifndef LIBEGL_MAIN_H_
- #define LIBEGL_MAIN_H_
- 
- #define EGLAPI
- #include <EGL/egl.h>
-+#include <EGL/eglext.h>
- 
- namespace egl
- {
- struct Current
- {
-     EGLint error;
-     EGLenum API;
-     EGLDisplay display;
-diff --git a/gfx/layers/d3d10/CanvasLayerD3D10.cpp b/gfx/layers/d3d10/CanvasLayerD3D10.cpp
---- a/gfx/layers/d3d10/CanvasLayerD3D10.cpp
-+++ b/gfx/layers/d3d10/CanvasLayerD3D10.cpp
-@@ -83,18 +83,22 @@ CanvasLayerD3D10::Initialize(const Data&
-   }
- 
-   mIsD2DTexture = PR_FALSE;
-   mUsingSharedTexture = PR_FALSE;
- 
-   HANDLE shareHandle = mGLContext ? mGLContext->GetD3DShareHandle() : nsnull;
-   if (shareHandle) {
-     HRESULT hr = device()->OpenSharedResource(shareHandle, __uuidof(ID3D10Texture2D), getter_AddRefs(mTexture));
--    if (SUCCEEDED(hr))
-+    if (SUCCEEDED(hr)) {
-       mUsingSharedTexture = PR_TRUE;
-+      // XXX for ANGLE, it's already the right-way up.  If we start using NV GL-D3D interop
-+      // however, we'll need to do the right thing.
-+      mNeedsYFlip = PR_FALSE;
-+    }
-   }
- 
-   if (!mUsingSharedTexture) {
-     CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, mBounds.width, mBounds.height, 1, 1);
-     desc.Usage = D3D10_USAGE_DYNAMIC;
-     desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
- 
-     HRESULT hr = device()->CreateTexture2D(&desc, NULL, getter_AddRefs(mTexture));
-diff --git a/gfx/thebes/GLContextProviderEGL.cpp b/gfx/thebes/GLContextProviderEGL.cpp
---- a/gfx/thebes/GLContextProviderEGL.cpp
-+++ b/gfx/thebes/GLContextProviderEGL.cpp
-@@ -391,18 +391,18 @@ public:
-             NS_WARNING("Couldn't find required entry points in EGL library (early init)");
-             return PR_FALSE;
-         }
- 
-         mEGLDisplay = fGetDisplay(EGL_DEFAULT_DISPLAY);
-         if (!fInitialize(mEGLDisplay, NULL, NULL))
-             return PR_FALSE;
- 
--        const char *vendor = (const char*) fQueryString(mEGLDisplay, LOCAL_EGL_VENDOR);
--        if (vendor && strstr(vendor, "TransGaming") != 0) {
-+        const char *version = (const char*) fQueryString(mEGLDisplay, LOCAL_EGL_VERSION);
-+        if (version && strstr(version, "ANGLE") != 0) {
-             mIsANGLE = PR_TRUE;
-         }
-         
-         const char *extensions = (const char*) fQueryString(mEGLDisplay, LOCAL_EGL_EXTENSIONS);
-         if (!extensions)
-             extensions = "";
- 
-         printf_stderr("Extensions: %s 0x%02x\n", extensions, extensions[0]);
new file mode 100644
--- /dev/null
+++ b/gfx/angle/angle-renaming-debug.patch
@@ -0,0 +1,222 @@
+# HG changeset patch
+# Parent 593e84b864c5470aa43682d308212878b0b4e5d9
+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 = \
+         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 \
+ 	$(NULL)
+ 
+ # flex/yacc generated files
+ CPPSRCS += \
+ 	glslang_lex.cpp \
+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
+@@ -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/debug.h"
++#include "compiler/compilerdebug.h"
+ 
+ namespace
+ {
+ TString getTypeName(const TType& type)
+ {
+     TInfoSinkBase out;
+     if (type.isMatrix())
+     {
+diff --git a/gfx/angle/src/compiler/OutputHLSL.cpp b/gfx/angle/src/compiler/OutputHLSL.cpp
+--- a/gfx/angle/src/compiler/OutputHLSL.cpp
++++ b/gfx/angle/src/compiler/OutputHLSL.cpp
+@@ -1,17 +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/OutputHLSL.h"
+ 
+-#include "compiler/debug.h"
++#include "compiler/compilerdebug.h"
+ #include "compiler/InfoSink.h"
+ #include "compiler/UnfoldSelect.h"
+ #include "compiler/SearchSymbol.h"
+ 
+ #include <stdio.h>
+ #include <algorithm>
+ 
+ namespace sh
+diff --git a/gfx/angle/src/compiler/Types.h b/gfx/angle/src/compiler/Types.h
+--- a/gfx/angle/src/compiler/Types.h
++++ b/gfx/angle/src/compiler/Types.h
+@@ -4,17 +4,17 @@
+ // found in the LICENSE file.
+ //
+ 
+ #ifndef _TYPES_INCLUDED
+ #define _TYPES_INCLUDED
+ 
+ #include "compiler/BaseTypes.h"
+ #include "compiler/Common.h"
+-#include "compiler/debug.h"
++#include "compiler/compilerdebug.h"
+ 
+ //
+ // Need to have association of line numbers to types in a list for building structs.
+ //
+ class TType;
+ struct TTypeLine {
+     TType* type;
+     int line;
+diff --git a/gfx/angle/src/compiler/compilerdebug.cpp b/gfx/angle/src/compiler/compilerdebug.cpp
+--- a/gfx/angle/src/compiler/compilerdebug.cpp
++++ b/gfx/angle/src/compiler/compilerdebug.cpp
+@@ -1,17 +1,17 @@
+ //
+ // 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.
+ //
+ 
+-// debug.cpp: Debugging utilities.
++// compilerdebug.cpp: Debugging utilities.
+ 
+-#include "compiler/debug.h"
++#include "compiler/compilerdebug.h"
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+ 
+ #include "compiler/ParseHelper.h"
+ 
+ static const int kTraceBufferLen = 1024;
+ 
+diff --git a/gfx/angle/src/compiler/compilerdebug.h b/gfx/angle/src/compiler/compilerdebug.h
+--- a/gfx/angle/src/compiler/compilerdebug.h
++++ b/gfx/angle/src/compiler/compilerdebug.h
+@@ -1,15 +1,15 @@
+ //
+ // 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.
+ //
+ 
+-// debug.h: Debugging utilities.
++// compilerdebug.h: Debugging utilities.
+ 
+ #ifndef COMPILER_DEBUG_H_
+ #define COMPILER_DEBUG_H_
+ 
+ #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
+@@ -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
+ 
+ 
+-#include "compiler/debug.h"
++#include "compiler/compilerdebug.h"
+ 
+ //
+ // Thread Local Storage Operations
+ //
+ #if defined(ANGLE_USE_NSPR)
+ typedef PRUintn OS_TLSIndex;
+ #define OS_INVALID_TLS_INDEX 0xFFFFFFFF
+ #elif defined(ANGLE_OS_WIN)
+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
+@@ -45,17 +45,17 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILI
+ //
+ // atom.c
+ //
+ 
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+ 
+-#include "compiler/debug.h"
++#include "compiler/compilerdebug.h"
+ #include "compiler/preprocessor/slglobals.h"
+ 
+ #undef malloc
+ #undef realloc
+ #undef free
+ 
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////// String table: //////////////////////////////////////
+diff --git a/gfx/angle/src/compiler/preprocessor/tokens.c b/gfx/angle/src/compiler/preprocessor/tokens.c
+--- a/gfx/angle/src/compiler/preprocessor/tokens.c
++++ b/gfx/angle/src/compiler/preprocessor/tokens.c
+@@ -45,17 +45,17 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILI
+ // tokens.c
+ //
+ 
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+ #include <ctype.h>
+ 
+-#include "compiler/debug.h"
++#include "compiler/compilerdebug.h"
+ #include "compiler/preprocessor/slglobals.h"
+ #include "compiler/util.h"
+ 
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////// Preprocessor and Token Recorder and Playback: ////////////////////////
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+ 
+ /*
new file mode 100644
--- /dev/null
+++ b/gfx/angle/extensions/ANGLE_framebuffer_blit.txt
@@ -0,0 +1,427 @@
+Name
+
+    ANGLE_framebuffer_blit
+
+Name Strings
+
+    GL_ANGLE_framebuffer_blit
+
+Contributors
+
+    Contributors to EXT_framebuffer_blit
+    Daniel Koch, TransGaming Inc.
+    Shannon Woods, TransGaming Inc.
+    Kenneth Russell, Google Inc.
+    Vangelis Kokkevis, Google Inc.
+
+Contact
+
+    Daniel Koch, TransGaming Inc. (daniel 'at' transgaming 'dot' com)
+
+Status
+
+    Implemented in ANGLE ES2
+
+Version
+
+    Last Modified Date: Aug 6, 2010
+    Author Revision: 3
+
+Number
+
+    OpenGL ES Extension #83
+
+Dependencies
+
+    OpenGL ES 2.0 is required.
+
+    The extension is written against the OpenGL ES 2.0 specification.
+
+    OES_texture_3D affects the definition of this extension.
+
+Overview
+
+    This extension modifies framebuffer objects by splitting the
+    framebuffer object binding point into separate DRAW and READ
+    bindings.  This allows copying directly from one framebuffer to
+    another.  In addition, a new high performance blit function is
+    added to facilitate these blits and perform some data conversion
+    where allowed.
+
+IP Status
+
+    No known IP claims.
+
+New Procedures and Functions
+
+    void BlitFramebufferANGLE(int srcX0, int srcY0, int srcX1, int srcY1,
+                              int dstX0, int dstY0, int dstX1, int dstY1,
+                              bitfield mask, enum filter);
+
+New Tokens
+
+    Accepted by the <target> parameter of BindFramebuffer,
+    CheckFramebufferStatus, FramebufferTexture2D, FramebufferTexture3DOES,
+    FramebufferRenderbuffer, and
+    GetFramebufferAttachmentParameteriv:
+
+    // (reusing the tokens from EXT_framebuffer_blit)
+    READ_FRAMEBUFFER_ANGLE                0x8CA8
+    DRAW_FRAMEBUFFER_ANGLE                0x8CA9
+
+    Accepted by the <pname> parameters of GetIntegerv and GetFloatv:
+
+    // (reusing the tokens from EXT_framebuffer_blit)
+    DRAW_FRAMEBUFFER_BINDING_ANGLE        0x8CA6 // alias FRAMEBUFFER_BINDING
+    READ_FRAMEBUFFER_BINDING_ANGLE        0x8CAA
+
+
+Additions to Chapter 3 of the OpenGL ES 2.0 Specification (Rasterization)
+
+    Change the last paragraph of section 3.7.2 (Alternate Texture Image
+    Specification Commands) to:
+
+    "Calling CopyTexSubImage3DOES, CopyTexImage2D or CopyTexSubImage2D will
+    result in an INVALID_FRAMEBUFFER_OPERATION error if the object bound
+    to READ_FRAMEBUFFER_BINDING_ANGLE is not "framebuffer complete"
+    (section 4.4.4.2)."
+
+Additions to Chapter 4 of the OpenGL ES 2.0 Specification (Per-Fragment
+Operations and the Framebuffer)
+
+    Change the first word of Chapter 4 from "The" to "A".
+
+    Append to the introduction of Chapter 4:
+
+    "Conceptually, the GL has two active framebuffers; the draw
+    framebuffer is the destination for rendering operations, and the
+    read framebuffer is the source for readback operations.  The same
+    framebuffer may be used for both drawing and reading.  Section
+    4.4.1 describes the mechanism for controlling framebuffer usage."
+
+    Modify the first sentence of the last paragraph of section 4.1.1 as follows:
+
+    "While an application-created framebuffer object is bound to
+    DRAW_FRAMEBUFFER_ANGLE, the pixel ownership test always passes."
+
+    Add to 4.3.1 (Reading Pixels), right before the subsection titled
+    "Obtaining Pixels from the Framebuffer":
+
+    "Calling ReadPixels generates INVALID_FRAMEBUFFER_OPERATION if
+    the object bound to READ_FRAMEBUFFER_BINDING_ANGLE is not "framebuffer
+    complete" (section 4.4.4.2)."
+
+    Insert a new section 4.3.2 titled "Copying Pixels" and renumber the
+    subsequent sections.  Add the following text:
+
+    "BlitFramebufferANGLE transfers a rectangle of pixel values from one
+    region of the read framebuffer to another in the draw framebuffer.
+
+    BlitFramebufferANGLE(int srcX0, int srcY0, int srcX1, int srcY1,
+                         int dstX0, int dstY0, int dstX1, int dstY1,
+                         bitfield mask, enum filter);
+
+    <mask> is the bitwise OR of a number of values indicating which
+    buffers are to be copied. The values are COLOR_BUFFER_BIT,
+    DEPTH_BUFFER_BIT, and STENCIL_BUFFER_BIT, which are described in
+    section 4.2.3.  The pixels corresponding to these buffers are
+    copied from the source rectangle, bound by the locations (srcX0,
+    srcY0) and (srcX1, srcY1), to the destination rectangle, bound by
+    the locations (dstX0, dstY0) and (dstX1, dstY1).  The lower bounds
+    of the rectangle are inclusive, while the upper bounds are
+    exclusive.
+
+    The actual region taken from the read framebuffer is limited to the
+    intersection of the source buffers being transferred, which may include
+    the color buffer, the depth buffer, and/or the stencil buffer depending on
+    <mask>. The actual region written to the draw framebuffer is limited to the
+    intersection of the destination buffers being written, which may include
+    the color buffer, the depth buffer, and/or the stencil buffer
+    depending on <mask>. Whether or not the source or destination regions are
+    altered due to these limits, the offset applied to pixels being transferred
+    is performed as though no such limits were present.
+
+    Stretching and scaling during a copy are not supported. If the source
+    and destination rectangle dimensions do not match, no copy is
+    performed and an INVALID_OPERATION error is generated.
+    Because stretching is not supported, <filter> must be NEAREST and
+    no filtering is applied. 
+
+    Flipping during a copy is not supported. If either the source or 
+    destination rectangle specifies a negative dimension, the error 
+    INVALID_OPERATION is generated. If both the source and 
+    destination rectangles specify a negative dimension for the same 
+    direction, no reversal is required and the operation is supported.
+
+    If the source and destination buffers are identical, and the
+    source and destination rectangles overlap, the result of the blit
+    operation is undefined.
+
+    The pixel copy bypasses the fragment pipeline.  The only fragment
+    operations which affect the blit are the pixel ownership test and
+    the scissor test.
+
+    If a buffer is specified in <mask> and does not exist in both the
+    read and draw framebuffers, the corresponding bit is silently
+    ignored.
+
+    Calling BlitFramebufferANGLE will result in an
+    INVALID_FRAMEBUFFER_OPERATION error if the objects bound to
+    DRAW_FRAMEBUFFER_BINDING_ANGLE and READ_FRAMEBUFFER_BINDING_ANGLE are
+    not "framebuffer complete" (section 4.4.4.2)."
+
+    Calling BlitFramebufferANGLE will result in an INVALID_OPERATION
+    error if <mask> includes COLOR_BUFFER_BIT and the source and 
+    destination color formats to not match.
+
+    Calling BlitFramebufferANGLE will result in an INVALID_OPERATION
+    error if <mask> includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT
+    and the source and destination depth and stencil buffer formats do
+    not match.
+
+    If <mask> includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT, only 
+    complete buffers can be copied.  If the source rectangle does not 
+    specify the complete source buffer or the destination rectangle 
+    (after factoring the scissor region, if applicable) does not specify 
+    the complete destination buffer, an INVALID_OPERATION
+    error is generated.
+
+    Modify the beginning of section 4.4.1 as follows:
+
+    "The default framebuffer for rendering and readback operations is
+    provided by the windowing system.  In addition, named framebuffer
+    objects can be created and operated upon.  The namespace for
+    framebuffer objects is the unsigned integers, with zero reserved
+    by the GL for the default framebuffer.
+
+    A framebuffer object is created by binding an unused name to
+    DRAW_FRAMEBUFFER_ANGLE or READ_FRAMEBUFFER_ANGLE.  The binding is
+    effected by calling
+
+        void BindFramebuffer(enum target, uint framebuffer);
+
+    with <target> set to the desired framebuffer target and
+    <framebuffer> set to the unused name.  The resulting framebuffer
+    object is a new state vector, comprising one set of the state values
+    listed in table 6.23 for each attachment point of the
+    framebuffer, set to the same initial values.  There is one
+    color attachment point, plus one each
+    for the depth and stencil attachment points.
+
+    BindFramebuffer may also be used to bind an existing
+    framebuffer object to DRAW_FRAMEBUFFER_ANGLE or
+    READ_FRAMEBUFFER_ANGLE.  If the bind is successful no change is made
+    to the state of the bound framebuffer object, and any previous
+    binding to <target> is broken.
+
+    If a framebuffer object is bound to DRAW_FRAMEBUFFER_ANGLE or
+    READ_FRAMEBUFFER_ANGLE, it becomes the target for rendering or
+    readback operations, respectively, until it is deleted or another
+    framebuffer is bound to the corresponding bind point.  Calling
+    BindFramebuffer with <target> set to FRAMEBUFFER binds the
+    framebuffer to both DRAW_FRAMEBUFFER_ANGLE and READ_FRAMEBUFFER_ANGLE.
+
+    While a framebuffer object is bound, GL operations on the target
+    to which it is bound affect the images attached to the bound
+    framebuffer object, and queries of the target to which it is bound
+    return state from the bound object.  Queries of the values
+    specified in table 6.20 (Implementation Dependent Pixel Depths)
+    and table 6.yy (Framebuffer Dependent Values) are
+    derived from the framebuffer object bound to DRAW_FRAMEBUFFER_ANGLE.
+
+    The initial state of DRAW_FRAMEBUFFER_ANGLE and READ_FRAMEBUFFER_ANGLE
+    refers to the default framebuffer provided by the windowing
+    system.  In order that access to the default framebuffer is not
+    lost, it is treated as a framebuffer object with the name of 0.
+    The default framebuffer is therefore rendered to and read from
+    while 0 is bound to the corresponding targets.  On some
+    implementations, the properties of the default framebuffer can
+    change over time (e.g., in response to windowing system events
+    such as attaching the context to a new windowing system drawable.)"
+
+    Change the description of DeleteFramebuffers as follows:
+
+    "<framebuffers> contains <n> names of framebuffer objects to be
+    deleted.  After a framebuffer object is deleted, it has no
+    attachments, and its name is again unused.  If a framebuffer that
+    is currently bound to one or more of the targets
+    DRAW_FRAMEBUFFER_ANGLE or READ_FRAMEBUFFER_ANGLE is deleted, it is as
+    though BindFramebuffer had been executed with the corresponding
+    <target> and <framebuffer> zero.  Unused names in <framebuffers>
+    are silently ignored, as is the value zero."
+
+
+    In section 4.4.3 (Renderbuffer Objects), modify the first two sentences
+    of the description of FramebufferRenderbuffer as follows:
+
+    "<target> must be DRAW_FRAMEBUFFER_ANGLE, READ_FRAMEBUFFER_ANGLE, or
+    FRAMEBUFFER.  If <target> is FRAMEBUFFER, it behaves as
+    though DRAW_FRAMEBUFFER_ANGLE was specified.  The INVALID_OPERATION 
+    error is generated if the value of the corresponding binding is zero."
+
+    In section 4.4.3 (Renderbuffer Objects), modify the first two sentences
+    of the description of FramebufferTexture2D as follows:
+
+    "<target> must be DRAW_FRAMEBUFFER_ANGLE,
+    READ_FRAMEBUFFER_ANGLE, or FRAMEBUFFER.  If <target> is
+    FRAMEBUFFER, it behaves as though DRAW_FRAMEBUFFER_ANGLE was
+    specified.  The INVALID_OPERATION error is generated if the value of the
+    corresponding binding is zero."
+
+    In section 4.4.5 (Framebuffer Completeness), modify the first sentence 
+    of the description of CheckFramebufferStatus as follows:
+
+    "If <target> is not DRAW_FRAMEBUFFER_ANGLE, READ_FRAMEBUFFER_ANGLE or
+    FRAMEBUFFER, the error INVALID_ENUM is generated.  If <target> is
+    FRAMEBUFFER, it behaves as though DRAW_FRAMEBUFFER_ANGLE was
+    specified."
+
+    Modify the first sentence of the subsection titled "Effects of Framebuffer
+    Completeness on Framebuffer Operations" to be:
+
+    "Attempting to render to or read from a framebuffer which is not
+    framebuffer complete will generate an
+    INVALID_FRAMEBUFFER_OPERATION error."
+    
+
+
+Additions to Chapter 6 of the OpenGL 1.5 Specification (State and State
+Requests)
+
+    In section 6.1.3, modify the first sentence of the description of
+    GetFramebufferAttachmentParameteriv as follows:
+
+    "<target> must be DRAW_FRAMEBUFFER_ANGLE, READ_FRAMEBUFFER_ANGLE or
+    FRAMEBUFFER.  If <target> is FRAMEBUFFER, it behaves as
+    though DRAW_FRAMEBUFFER_ANGLE was specified."
+
+    Modify the title of Table 6.23 (Framebuffer State) to be "Framebuffer 
+    (state per attachment point)". 
+
+
+Dependencies on OES_texture_3D
+
+    On an OpenGL ES implementation, in the absense of OES_texture_3D,
+    omit references to FramebufferTexture3DOES and CopyTexSubImage3DOES.
+
+Errors
+
+    The error INVALID_FRAMEBUFFER_OPERATION is generated if
+    BlitFramebufferANGLE is called while the
+    draw framebuffer is not framebuffer complete.
+
+    The error INVALID_FRAMEBUFFER_OPERATION is generated if
+    BlitFramebufferANGLE, ReadPixels, CopyTex{Sub}Image*, is called while the
+    read framebuffer is not framebuffer complete.
+
+    The error INVALID_VALUE is generated by BlitFramebufferANGLE if
+    <mask> has any bits set other than those named by
+    COLOR_BUFFER_BIT, DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT.
+
+    The error INVALID_OPERATION is generated if BlitFramebufferANGLE is
+    called and <mask> includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT
+    and the source and destination depth or stencil buffer formats do
+    not match.
+
+    The error INVALID_OPERATION is generated if BlitFramebufferANGLE is 
+    called and any of the following conditions are true:
+     - the source and destination rectangle dimensions do not match
+       (ie scaling or flipping is required).
+     - <mask> includes COLOR_BUFFER_BIT and the source and destination 
+       buffer formats do not match.
+     - <mask> includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT and the
+       source or destination rectangles do not specify the entire source
+       or destination buffer (after applying any scissor region).
+
+    The error INVALID_ENUM is generated by BlitFramebufferANGLE if
+    <filter> is not NEAREST.
+
+    The error INVALID_ENUM is generated if BindFramebuffer,
+    CheckFramebufferStatus, FramebufferTexture{2D|3DOES},
+    FramebufferRenderbuffer, or
+    GetFramebufferAttachmentParameteriv is called and <target> is
+    not DRAW_FRAMEBUFFER_ANGLE, READ_FRAMEBUFFER_ANGLE or FRAMEBUFFER.
+
+New State
+
+    (Add a new table 6.xx, "Framebuffer (state per framebuffer target binding point)")
+
+    Get Value                     Type   Get Command   Initial Value    Description               Section
+    ------------------------------  ----   -----------   --------------   -------------------       ------------
+    DRAW_FRAMEBUFFER_BINDING_ANGLE   Z+    GetIntegerv   0                framebuffer object bound  4.4.1
+                                                                          to DRAW_FRAMEBUFFER_ANGLE
+    READ_FRAMEBUFFER_BINDING_ANGLE   Z+    GetIntegerv   0                framebuffer object        4.4.1
+                                                                          to READ_FRAMEBUFFER_ANGLE
+
+    Remove reference to FRAMEBUFFER_BINDING from Table 6.23.
+
+    (Add a new table 6.yy, "Framebuffer Dependent Values") 
+
+    Get Value                     Type   Get Command   Initial Value    Description               Section
+    ----------------------------  ----   -----------   --------------   -------------------       ------------
+    SAMPLE_BUFFERS                 Z+    GetIntegerv   0                Number of multisample     3.2
+                                                                        buffers
+    SAMPLES                        Z+    GetIntegerv   0                Coverage mask size        3.2
+
+    Remove the references to SAMPLE_BUFFERS and SAMPLES from Table 6.17.
+
+
+Issues
+
+    1) What should we call this extension?
+  
+       Resolved: ANGLE_framebuffer_blit.  
+
+       This extension is a result of a collaboration between Google and 
+       TransGaming for the open-source ANGLE project. Typically one would
+       label a multi-vendor extension as EXT, but EXT_framebuffer_blit 
+       is already the name for this on Desktop GL.  Additionally this
+       isn't truely a multi-vendor extension because there is only one
+       implementation of this.  We'll follow the example of the open-source
+       MESA project which uses the project name for the vendor suffix.
+
+    2) Why is this done as a separate extension instead of just supporting
+       EXT_framebuffer_blit?
+
+       To date, EXT_framebuffer_blit has not had interactions with OpenGL ES
+       specified and, as far as we know, it has not previously been exposed on 
+       an ES 1.1 or ES 2.0 implementation. Because there are enough 
+       differences between Desktop GL and OpenGL ES, and since OpenGL ES 2.0 
+       has already subsumed the EXT_framebuffer_object functionality (with 
+       some changes) it was deemed a worthwhile exercise to fully specify the
+       interactions.  Additionally, some of the choices in exactly which 
+       functionality is supported by BlitFramebufferANGLE is dictated by
+       what is reasonable to support on a implementation which is 
+       layered on Direct3D9.  It is not expected that other implementations 
+       will necessary have the same set of restrictions or requirements. 
+
+    3) How does this extension differ from EXT_framebuffer_blit?
+
+       This extension is designed to be a pure subset of the 
+       EXT_framebuffer_blit functionality as applicable to OpenGL ES 2.0.
+
+       Functionality that is unchanged:
+        - the split DRAW and READ framebuffer attachment points and related sematics.
+        - the token values for the DRAW/READ_FRAMEBUFFER and DRAW/READ_FRAMBUFFER_BINDING
+        - the signature of the BlitFramebuffer entry-point.
+       
+       Additional restrictions imposed by BlitFramebufferANGLE:
+        - no color conversions are supported
+        - no scaling, stretching or flipping are supported
+        - no filtering is supported (a consequence of no stretching)
+        - only whole depth and/or stencil buffers can be copied
+
+Revision History
+
+    Revision 1, 2010/07/06
+      - copied from revision 15 of EXT_framebuffer_object
+      - removed language that was clearly not relevant to ES2
+      - rebased changes against the OpenGL ES 2.0 specification
+      - added ANGLE-specific restrictions
+    Revision 2, 2010/07/15
+      - clarifications of implicit clamping to buffer sizes (from ARB_fbo)
+      - clarify that D/S restricts apply after the scissor is applied
+      - improve some error language
+    Revision 3, 2010/08/06
+      - add additional contributors, update implementation status
+
new file mode 100644
--- /dev/null
+++ b/gfx/angle/extensions/ANGLE_framebuffer_multisample.txt
@@ -0,0 +1,363 @@
+Name
+
+    ANGLE_framebuffer_multisample
+
+Name Strings
+
+    GL_ANGLE_framebuffer_multisample
+
+Contributors
+
+    Contributors to EXT_framebuffer_multisample
+    Daniel Koch, TransGaming Inc.
+    Shannon Woods, TransGaming Inc.
+    Kenneth Russell, Google Inc.
+    Vangelis Kokkevis, Google Inc.
+
+Contacts
+
+    Daniel Koch, TransGaming Inc. (daniel 'at' transgaming 'dot' com)
+
+Status
+
+    Implemented in ANGLE ES2
+
+Version
+
+    Last Modified Date: Aug 6, 2010 
+    Author Revision: #3
+
+Number
+
+    OpenGL ES Extension #84
+
+Dependencies
+
+    Requires OpenGL ES 2.0.
+
+    Requires GL_ANGLE_framebuffer_blit (or equivalent functionality).
+
+    The extension is written against the OpenGL ES 2.0 specification. 
+
+    OES_texture_3D affects the definition of this extension.
+
+Overview
+
+    This extension extends the framebuffer object framework to
+    enable multisample rendering.
+
+    The new operation RenderbufferStorageMultisampleANGLE() allocates
+    storage for a renderbuffer object that can be used as a multisample
+    buffer.  A multisample render buffer image differs from a
+    single-sample render buffer image in that a multisample image has a
+    number of SAMPLES that is greater than zero.  No method is provided
+    for creating multisample texture images.
+
+    All of the framebuffer-attachable images attached to a framebuffer
+    object must have the same number of SAMPLES or else the framebuffer
+    object is not "framebuffer complete".  If a framebuffer object with
+    multisample attachments is "framebuffer complete", then the
+    framebuffer object behaves as if SAMPLE_BUFFERS is one.
+
+    The resolve operation is affected by calling 
+    BlitFramebufferANGLE (provided by the ANGLE_framebuffer_blit
+    extension) where the source is a multisample application-created
+    framebuffer object and the destination is a single-sample
+    framebuffer object (either application-created or window-system
+    provided).
+
+New Procedures and Functions
+
+    void RenderbufferStorageMultisampleANGLE(
+            enum target, sizei samples,
+            enum internalformat,
+            sizei width, sizei height);
+
+New Types
+
+    None.
+
+New Tokens
+
+    Accepted by the <pname> parameter of GetRenderbufferParameteriv:
+
+        RENDERBUFFER_SAMPLES_ANGLE                  0x8CAB
+
+    Returned by CheckFramebufferStatus:
+
+        FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE    0x8D56
+
+    Accepted by the <pname> parameter of GetBooleanv, GetIntegerv,
+    and GetFloatv:
+
+        MAX_SAMPLES_ANGLE                           0x8D57
+
+Additions to Chapter 2 of the OpenGL ES 2.0 Specification (OpenGL Operation)
+
+Additions to Chapter 3 of the OpenGL ES 2.0 Specification (Rasterization)
+
+    Add to the last paragraph of 3.7.2 (Alternate Texture Image Specification)
+    (as modified by ANGLE_framebuffer_blit) the following:
+
+    "Calling CopyTexSubImage3DOES, CopyTexImage2D or CopyTexSubImage2D will
+    result in INVALID_OPERATION being generated if the object bound to
+    READ_FRAMEBUFFER_BINDING_ANGLE is "framebuffer complete" and the value
+    of SAMPLE_BUFFERS is greater than zero."
+
+Additions to Chapter 4 of the OpenGL ES 2.0 Specification (Per-Fragment
+Operations and the Framebuffer)
+
+    Add to 4.3.1 (Reading Pixels), right before the subsection titled
+    "Obtaining Pixels from the Framebuffer":
+
+    "ReadPixels generates INVALID_OPERATION if READ_FRAMEBUFFER_BINDING_ANGLE
+    (section 4.4) is non-zero, the read framebuffer is framebuffer
+    complete, and the value of SAMPLE_BUFFERS for the read framebuffer
+    is greater than zero."
+
+    In 4.3.2 (Copying Pixels), add to the section describing BlitFramebuffer
+    that was added by ANGLE_framebuffer_blit.
+
+    "If SAMPLE_BUFFERS for the read framebuffer is greater than zero and
+    SAMPLE_BUFFERS for the draw framebuffer is zero, the samples
+    corresponding to each pixel location in the source are converted to
+    a single sample before being written to the destination.
+
+    If SAMPLE_BUFFERS for the draw framebuffer is greater than zero, 
+    no copy is performed and an INVALID_OPERATION error is generated.
+
+    If SAMPLE_BUFFERS for the read framebuffer is greater than zero and
+    <mask> includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT, no copy is 
+    performed and an INVALID_OPERATION error is generated.
+
+    If SAMPLE_BUFFERS for the read framebuffer is greater than zero and 
+    the format of the read and draw framebuffers are not identical, no
+    copy is performed and an INVALID_OPERATION error is generated.
+
+    If SAMPLE_BUFFERS for the read framebuffer is greater than zero, the
+    dimensions of the source and destination rectangles provided to 
+    BlitFramebufferANGLE must be identical and must specify the complete 
+    source and destination buffers, otherwise no copy is performed and 
+    an INVALID_OPERATION error is generated."
+
+    Modification to 4.4.3 (Renderbuffer Objects)
+
+    Add, just above the definition of RenderbufferStorage:
+
+    "The command
+
+        void RenderbufferStorageMultisampleANGLE(
+            enum target, sizei samples,
+            enum internalformat,
+            sizei width, sizei height);
+
+    establishes the data storage, format, dimensions, and number of
+    samples of a renderbuffer object's image.  <target> must be
+    RENDERBUFFER.  <internalformat> must be one of the color-renderable,
+    depth-renderable, or stencil-renderable formats described in table 4.5.
+    <width> and <height> are the dimensions in pixels of the renderbuffer.  If
+    either <width> or <height> is greater than the value of 
+    MAX_RENDERBUFFER_SIZE, or if <samples> is greater than MAX_SAMPLES_ANGLE, 
+    then the error INVALID_VALUE is generated. If OpenGL ES is unable to 
+    create a data store of the requested size, the error OUT_OF_MEMORY 
+    is generated.
+
+    Upon success, RenderbufferStorageMultisampleANGLE deletes any existing
+    data store for the renderbuffer image and the contents of the data
+    store after calling RenderbufferStorageMultisampleANGLE are undefined.
+    RENDERBUFFER_WIDTH is set to <width>, RENDERBUFFER_HEIGHT is
+    set to <height>, and RENDERBUFFER_INTERNAL_FORMAT is set to
+    <internalformat>.
+
+    If <samples> is zero, then RENDERBUFFER_SAMPLES_ANGLE is set to zero.
+    Otherwise <samples> represents a request for a desired minimum
+    number of samples. Since different implementations may support
+    different sample counts for multisampled rendering, the actual
+    number of samples allocated for the renderbuffer image is
+    implementation dependent.  However, the resulting value for
+    RENDERBUFFER_SAMPLES_ANGLE is guaranteed to be greater than or equal
+    to <samples> and no more than the next larger sample count supported
+    by the implementation.
+
+    An OpenGL ES implementation may vary its allocation of internal component
+    resolution based on any RenderbufferStorageMultisampleANGLE parameter (except
+    target), but the allocation and chosen internal format must not be a
+    function of any other state and cannot be changed once they are
+    established. The actual resolution in bits of each component of the 
+    allocated image can be queried with GetRenderbufferParameteriv."
+
+    Modify the definiton of RenderbufferStorage as follows:
+
+    "The command
+
+        void RenderbufferStorage(enum target, enum internalformat,
+                                    sizei width, sizei height);
+
+     is equivalent to calling RenderbufferStorageMultisampleANGLE with
+     <samples> equal to zero."
+
+    In section 4.4.5 (Framebuffer Completeness) in the subsection
+    titled "Framebuffer Completeness" add an entry to the bullet list:
+
+    * The value of RENDERBUFFER_SAMPLES_ANGLE is the same for all attached
+      images.
+      { FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE }
+
+    Also add a paragraph to the end of the section after the definition
+    of CheckFramebufferStatus:
+
+    "The values of SAMPLE_BUFFERS and SAMPLES are derived from the
+    attachments of the currently bound framebuffer object.  If the
+    current DRAW_FRAMEBUFFER_BINDING_ANGLE is not "framebuffer complete",
+    then both SAMPLE_BUFFERS and SAMPLES are undefined.  Otherwise,
+    SAMPLES is equal to the value of RENDERBUFFER_SAMPLES_ANGLE for the
+    attached images (which all must have the same value for
+    RENDERBUFFER_SAMPLES_ANGLE).  Further, SAMPLE_BUFFERS is one if
+    SAMPLES is non-zero.  Otherwise, SAMPLE_BUFFERS is zero.
+
+Additions to Chapter 5 of the OpenGL ES 2.0 Specification (Special Functions)
+
+
+Additions to Chapter 6 of the OpenGL ES 2.0 Specification (State and State
+Requests)
+
+    In section 6.1.3 (Enumeraged Queries), modify the third paragraph 
+    of the description of GetRenderbufferParameteriv as follows:
+
+    "Upon successful return from GetRenderbufferParameteriv, if
+    <pname> is RENDERBUFFER_WIDTH, RENDERBUFFER_HEIGHT,
+    RENDERBUFFER_INTERNAL_FORMAT, or RENDERBUFFER_SAMPLES_ANGLE, then <params> 
+    will contain the width in pixels, height in pixels, internal format, or 
+    number of samples, respectively, of the image of the renderbuffer 
+    currently bound to <target>."
+
+
+Dependencies on ANGLE_framebuffer_blit    
+
+    ANGLE_framebuffer_blit is required.  Technically, ANGLE_framebuffer_blit
+    would not be required to support multisampled rendering, except for
+    the fact that it provides the only method of doing a multisample
+    resovle from a multisample renderbuffer.
+
+Dependencies on OES_texture_3D
+
+    On an OpenGL ES implementation, in the absense of OES_texture_3D,
+    omit references to CopyTexSubImage3DOES.
+
+Errors
+
+    The error INVALID_OPERATION is generated if ReadPixels or 
+    CopyTex{Sub}Image* is called while READ_FRAMEBUFFER_BINDING_ANGLE
+    is non-zero, the read framebuffer is framebuffer complete, and the
+    value of SAMPLE_BUFFERS for the read framebuffer is greater than
+    zero.
+
+    If both the draw and read framebuffers are framebuffer complete and
+    the draw framebuffer has a value of SAMPLE_BUFFERS that is greater 
+    than zero, then the error INVALID_OPERATION is generated if 
+    BlitFramebufferANGLE is called.
+
+    If both the draw and read framebuffers are framebuffer complete and
+    the read framebuffer has a value of SAMPLE_BUFFERS that is greater
+    than zero, the error INVALID_OPERATION is generated if 
+    BlitFramebufferANGLE is called and any of the following conditions
+    are true:
+     - <mask> includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT.
+     - the source or destination rectangles do not specify the entire
+       source or destination buffer.
+
+    If both the draw and read framebuffers are framebuffer complete and
+    either has a value of SAMPLE_BUFFERS that is greater than zero, then
+    the error INVALID_OPERATION is generated if BlitFramebufferANGLE is
+    called and the formats of the draw and read framebuffers are not
+    identical.
+
+    If either the draw or read framebuffer is framebuffer complete and
+    has a value of SAMPLE_BUFFERS that is greater than zero, then the
+    error INVALID_OPERATION is generated if BlitFramebufferANGLE is called
+    and the specified source and destination dimensions are not
+    identical.
+
+    If RenderbufferStorageMultisampleANGLE is called with <target> not
+    equal to RENDERBUFFER, the error INVALID_ENUM is generated.
+
+    If RenderbufferStorageMultisampleANGLE is called with an 
+    <internalformat> that is not listed as one of the color-, depth- 
+    or stencil-renderable formats in Table 4.5, then the error
+    INVALID_ENUM is generated.
+
+    If RenderbufferStorageMultisampleANGLE is called with <width> or 
+    <height> greater than MAX_RENDERBUFFER_SIZE, then the error 
+    INVALID_VALUE is generated.
+
+    If RenderbufferStorageMultisampleANGLE is called with a value of
+    <samples> that is greater than MAX_SAMPLES_ANGLE or less than zero,
+    then the error INVALID_VALUE is generated.
+
+    The error OUT_OF_MEMORY is generated when
+    RenderbufferStorageMultisampleANGLE cannot create storage of the
+    specified size.
+
+New State
+
+    Add to table 6.22 (Renderbuffer State)
+
+    Get Value                          Type    Get Command                 Initial Value  Description             Section
+    -------------------------------    ------  --------------------------  -------------  --------------------    -------
+    RENDERBUFFER_SAMPLES_ANGLE         Z+      GetRenderbufferParameteriv  0              number of samples       4.4.3
+
+
+    Add to table 6.yy (Framebuffer Dependent Vaues) (added by 
+    ANGLE_framebuffer_blit), the following new framebuffer dependent state.
+
+    Get Value          Type  Get Command     Minimum Value    Description             Section
+    -----------------  ----  -----------     -------------    -------------------     -------
+    MAX_SAMPLES_ANGLE  Z+    GetIntegerv     1                Maximum number of       4.4.3
+                                                              samples supported
+                                                              for multisampling
+                                                            
+
+
+Issues
+    
+    Issues from EXT_framebuffer_multisample have been removed.
+ 
+    1) What should we call this extension?
+
+       Resolved: ANGLE_framebuffer_blit.  
+
+       This extension is a result of a collaboration between Google and 
+       TransGaming for the open-source ANGLE project. Typically one would
+       label a multi-vendor extension as EXT, but EXT_framebuffer_mulitsample 
+       is already the name for this on Desktop GL.  Additionally this
+       isn't truely a multi-vendor extension because there is only one
+       implementation of this.  We'll follow the example of the open-source
+       MESA project which uses the project name for the vendor suffix.
+ 
+    2) How does this extension differ from EXT_framebuffer_multisample?
+
+       This is designed to be a proper subset of EXT_framebuffer_multisample
+       functionality as applicable to OpenGL ES 2.0.
+
+       Functionality that is unchanged: 
+        - creation of multisample renderbuffers.
+        - whole buffer multi-sample->single-sample resolve.
+        - no format conversions, stretching or flipping supported on multisample blits.
+
+       Additional restrictions on BlitFramebufferANGLE:
+        - multisample resolve is only supported on color buffers.
+        - no blits to multisample destinations (no single->multi or multi-multi).
+        - only entire buffers can be resolved.
+         
+Revision History
+
+    Revision 1, 2010/07/08
+      - copied from revision 7 of EXT_framebuffer_multisample
+      - removed language that was not relevant to ES2 
+      - rebase changes against the Open GL ES 2.0 specification
+      - added ANGLE-specific restrictions
+    Revision 2, 2010/07/19
+      - fix missing error code
+    Revision 3, 2010/08/06
+      - add additional contributors, update implementation status
+      - disallow negative samples 
new file mode 100644
--- /dev/null
+++ b/gfx/angle/extensions/ANGLE_timer_query.txt
@@ -0,0 +1,591 @@
+Name
+
+    ANGLE_timer_query
+
+Name Strings
+
+    GL_ANGLE_timer_query
+
+Contributors
+
+    Contributors to ARB_occlusion_query
+    Contributors to EXT_timer_query
+    Contributors to ARB_timer_query
+    Ben Vanik, Google Inc.
+    Daniel Koch, TransGaming Inc.
+
+Contact
+
+    Ben Vanik, Google Inc. (benvanik 'at' google 'dot' com)
+
+Status
+
+    Draft
+
+Version
+
+    Last Modified Date: Apr 28, 2011
+    Author Revision: 1
+
+Number
+
+    OpenGL ES Extension #??
+
+Dependencies
+
+    OpenGL ES 2.0 is required.
+
+    The extension is written against the OpenGL ES 2.0 specification.
+
+Overview
+
+    Applications can benefit from accurate timing information in a number of
+    different ways.  During application development, timing information can
+    help identify application or driver bottlenecks.  At run time,
+    applications can use timing information to dynamically adjust the amount
+    of detail in a scene to achieve constant frame rates.  OpenGL
+    implementations have historically provided little to no useful timing
+    information.  Applications can get some idea of timing by reading timers
+    on the CPU, but these timers are not synchronized with the graphics
+    rendering pipeline.  Reading a CPU timer does not guarantee the completion
+    of a potentially large amount of graphics work accumulated before the
+    timer is read, and will thus produce wildly inaccurate results.
+    glFinish() can be used to determine when previous rendering commands have
+    been completed, but will idle the graphics pipeline and adversely affect
+    application performance.
+
+    This extension provides a query mechanism that can be used to determine
+    the amount of time it takes to fully complete a set of GL commands, and
+    without stalling the rendering pipeline.  It uses the query object
+    mechanisms first introduced in the occlusion query extension, which allow
+    time intervals to be polled asynchronously by the application.
+
+IP Status
+
+    No known IP claims.
+
+New Procedures and Functions
+
+    void GenQueriesANGLE(sizei n, uint *ids);
+    void DeleteQueriesANGLE(sizei n, const uint *ids);
+    boolean IsQueryANGLE(uint id);
+    void BeginQueryANGLE(enum target, uint id);
+    void EndQueryANGLE(enum target);
+    void QueryCounterANGLE(uint id, enum target);
+    void GetQueryivANGLE(enum target, enum pname, int *params);
+    void GetQueryObjectivANGLE(uint id, enum pname, int *params);
+    void GetQueryObjectuivANGLE(uint id, enum pname, uint *params);
+    void GetQueryObjecti64vANGLE(uint id, enum pname, int64 *params);
+    void GetQueryObjectui64vANGLE(uint id, enum pname, uint64 *params);
+
+New Tokens
+
+    Accepted by the <pname> parameter of GetQueryivANGLE:
+
+        QUERY_COUNTER_BITS_ANGLE                       0x8864
+        CURRENT_QUERY_ANGLE                            0x8865
+
+    Accepted by the <pname> parameter of GetQueryObjectivANGLE,
+    GetQueryObjectuivANGLE, GetQueryObjecti64vANGLE, and
+    GetQueryObjectui64vANGLE:
+
+        QUERY_RESULT_ANGLE                             0x8866
+        QUERY_RESULT_AVAILABLE_ANGLE                   0x8867
+        
+    Accepted by the <target> parameter of BeginQueryANGLE, EndQueryANGLE, and
+    GetQueryivANGLE:
+
+        TIME_ELAPSED_ANGLE                             0x88BF
+
+    Accepted by the <target> parameter of GetQueryivANGLE and
+    QueryCounterANGLE:
+
+        TIMESTAMP_ANGLE                                0x8E28
+
+Additions to Chapter 2 of the OpenGL ES 2.0 Specification (OpenGL ES Operation)
+
+    (Modify table 2.1, Correspondence of command suffix letters to GL argument)
+    Add two new types:
+    
+    Letter Corresponding GL Type
+    ------ ---------------------
+    i64    int64ANGLE
+    ui64   uint64ANGLE
+
+    (Modify table 2.2, GL data types) Add two new types:
+    
+    GL Type       Minimum Bit Width   Description
+    -------       -----------------   -----------------------------
+    int64ANGLE    64                  Signed 2's complement integer
+    uint64ANGLE   64                  Unsigned binary integer
+
+Additions to Chapter 5 of the OpenGL ES 2.0 Specification (Special Functions)
+
+    Add a new section 5.3 "Timer Queries":
+
+    "5.3  Timer Queries
+
+    Timer queries use query objects to track the amount of time needed to
+    fully complete a set of GL commands, or to determine the current time
+    of the GL.
+    
+    Timer queries are associated with query objects.  The command
+
+      void GenQueriesANGLE(sizei n, uint *ids);
+
+    returns <n> previously unused query object names in <ids>.  These
+    names are marked as used, but no object is associated with them until
+    the first time they are used by BeginQueryANGLE.  Query objects contain
+    one piece of state, an integer result value.  This result value is
+    initialized to zero when the object is created.  Any positive integer
+    except for zero (which is reserved for the GL) is a valid query
+    object name.
+
+    Query objects are deleted by calling
+
+      void DeleteQueriesANGLE(sizei n, const uint *ids);
+
+    <ids> contains <n> names of query objects to be deleted.  After a
+    query object is deleted, its name is again unused.  Unused names in
+    <ids> are silently ignored.
+    If an active query object is deleted its name immediately becomes unused,
+    but the underlying object is not deleted until it is no longer active.
+
+    A timer query can be started and finished by calling
+
+      void BeginQueryANGLE(enum target, uint id);
+      void EndQueryANGLE(enum target);
+
+    where <target> is TIME_ELAPSED_ANGLE.  If BeginQueryANGLE is called
+    with an unused <id>, that name is marked as used and associated with
+    a new query object.
+    
+    If BeginQueryANGLE is called with an <id> of zero, if the active query
+    object name for <target> is non-zero, if <id> is the name of an existing
+    query object whose type does not match <target>, or if <id> is the active
+    query object name for any query type, the error INVALID_OPERATION is
+    generated.  If EndQueryANGLE is called while no query with the same target
+    is in progress, an INVALID_OPERATION error is generated.
+
+    When BeginQueryANGLE and EndQueryANGLE are called with a <target> of
+    TIME_ELAPSED_ANGLE, the GL prepares to start and stop the timer used for
+    timer queries.  The timer is started or stopped when the effects from all
+    previous commands on the GL client and server state and the framebuffer
+    have been fully realized.  The BeginQueryANGLE and EndQueryANGLE commands
+    may return before the timer is actually started or stopped.  When the timer
+    query timer is finally stopped, the elapsed time (in nanoseconds) is
+    written to the corresponding query object as the query result value, and
+    the query result for that object is marked as available.
+
+    If the elapsed time overflows the number of bits, <n>, available to hold
+    elapsed time, its value becomes undefined.  It is recommended, but not
+    required, that implementations handle this overflow case by saturating at
+    2^n - 1.
+
+    The necessary state is a single bit indicating whether an timer
+    query is active, the identifier of the currently active timer
+    query, and a counter keeping track of the time that has passed.
+
+    When the command
+
+         void QueryCounterANGLE(uint id, enum target);
+
+    is called with <target> TIMESTAMP_ANGLE, the GL records the current time
+    into the corresponding query object. The time is recorded after all
+    previous commands on the GL client and server state and the framebuffer
+    have been fully realized. When the time is recorded, the query result for
+    that object is marked available. QueryCounterANGLE timer queries can be
+    used within a BeginQueryANGLE / EndQueryANGLE block where the <target> is
+    TIME_ELAPSED_ANGLE and it does not affect the result of that query object.
+    The error INVALID_OPERATION is generated if the <id> is already in use
+    within a BeginQueryANGLE/EndQueryANGLE block."
+
+Additions to Chapter 6 of the OpenGL ES 2.0 Specification (State and State
+Requests)
+
+    Add a new section 6.1.9 "Timer Queries":
+
+    "The command
+
+      boolean IsQueryANGLE(uint id);
+
+    returns TRUE if <id> is the name of a query object.  If <id> is zero,
+    or if <id> is a non-zero value that is not the name of a query
+    object, IsQueryANGLE returns FALSE.
+
+    Information about a query target can be queried with the command
+
+      void GetQueryivANGLE(enum target, enum pname, int *params);
+
+    <target> identifies the query target and can be TIME_ELAPSED_ANGLE or
+    TIMESTAMP_ANGLE for timer queries.
+
+    If <pname> is CURRENT_QUERY_ANGLE, the name of the currently active query
+    for <target>, or zero if no query is active, will be placed in <params>.
+
+    If <pname> is QUERY_COUNTER_BITS_ANGLE, the implementation-dependent number
+    of bits used to hold the query result for <target> will be placed in
+    <params>.  The number of query counter bits may be zero, in which case
+    the counter contains no useful information.
+
+    For timer queries (TIME_ELAPSED_ANGLE and TIMESTAMP_ANGLE), if the number
+    of bits is non-zero, the minimum number of bits allowed is 30 which
+    will allow at least 1 second of timing.
+
+    The state of a query object can be queried with the commands
+
+      void GetQueryObjectivANGLE(uint id, enum pname, int *params);
+      void GetQueryObjectuivANGLE(uint id, enum pname, uint *params);
+      void GetQueryObjecti64vANGLE(uint id, enum pname, int64 *params);
+      void GetQueryObjectui64vANGLE(uint id, enum pname, uint64 *params);
+
+    If <id> is not the name of a query object, or if the query object
+    named by <id> is currently active, then an INVALID_OPERATION error is
+    generated.
+
+    If <pname> is QUERY_RESULT_ANGLE, then the query object's result
+    value is returned as a single integer in <params>. If the value is so
+    large in magnitude that it cannot be represented with the requested type,
+    then the nearest value representable using the requested type is
+    returned. If the number of query counter bits for target is zero, then
+    the result is returned as a single integer with the value zero.
+    
+    There may be an indeterminate delay before the above query returns. If
+    <pname> is QUERY_RESULT_AVAILABLE_ANGLE, FALSE is returned if such a delay
+    would be required; otherwise TRUE is returned. It must always be true
+    that if any query object returns a result available of TRUE, all queries
+    of the same type issued prior to that query must also return TRUE.
+
+    Querying the state for a given timer query forces that timer query to
+    complete within a finite amount of time.
+
+    If multiple queries are issued on the same target and id prior to 
+    calling GetQueryObject[u]i[64]vANGLE, the result returned will always be
+    from the last query issued.  The results from any queries before the
+    last one will be lost if the results are not retrieved before starting
+    a new query on the same <target> and <id>."
+
+Errors
+
+    The error INVALID_VALUE is generated if GenQueriesANGLE is called where
+    <n> is negative.
+
+    The error INVALID_VALUE is generated if DeleteQueriesANGLE is called
+    where <n> is negative.
+
+    The error INVALID_OPERATION is generated if BeginQueryANGLE is called
+    when a query of the given <target> is already active.
+
+    The error INVALID_OPERATION is generated if EndQueryANGLE is called
+    when a query of the given <target> is not active.
+
+    The error INVALID_OPERATION is generated if BeginQueryANGLE is called
+    where <id> is zero.
+
+    The error INVALID_OPERATION is generated if BeginQueryANGLE is called
+    where <id> is the name of a query currently in progress.
+    
+    The error INVALID_OPERATION is generated if BeginQueryANGLE is called
+    where <id> is the name of an existing query object whose type does not
+    match <target>.
+
+    The error INVALID_ENUM is generated if BeginQueryANGLE or EndQueryANGLE
+    is called where <target> is not TIME_ELAPSED_ANGLE.
+
+    The error INVALID_ENUM is generated if GetQueryivANGLE is called where
+    <target> is not TIME_ELAPSED_ANGLE or TIMESTAMP_ANGLE.
+
+    The error INVALID_ENUM is generated if GetQueryivANGLE is called where
+    <pname> is not QUERY_COUNTER_BITS_ANGLE or CURRENT_QUERY_ANGLE.
+
+    The error INVALID_ENUM is generated if QueryCounterANGLE is called where
+    <target> is not TIMESTAMP_ANGLE.
+
+    The error INVALID_OPERATION is generated if QueryCounterANGLE is called
+    on a query object that is already in use inside a
+    BeginQueryANGLE/EndQueryANGLE.
+
+    The error INVALID_OPERATION is generated if GetQueryObjectivANGLE,
+    GetQueryObjectuivANGLE, GetQueryObjecti64vANGLE, or
+    GetQueryObjectui64vANGLE is called where <id> is not the name of a query
+    object.
+
+    The error INVALID_OPERATION is generated if GetQueryObjectivANGLE,
+    GetQueryObjectuivANGLE, GetQueryObjecti64vANGLE, or
+    GetQueryObjectui64vANGLE is called where <id> is the name of a currently
+    active query object.
+
+    The error INVALID_ENUM is generated if GetQueryObjectivANGLE,
+    GetQueryObjectuivANGLE, GetQueryObjecti64vANGLE, or
+    GetQueryObjectui64vANGLE is called where <pname> is not
+    QUERY_RESULT_ANGLE or QUERY_RESULT_AVAILABLE_ANGLE.
+
+New State
+
+    (Add a new table 6.xx, "Query Operations")
+    
+    Get Value                      Type    Get Command              Initial Value   Description              Sec
+    ---------                      ----    -----------              -------------   -----------              ------
+    -                              B       -                        FALSE           query active             5.3
+    CURRENT_QUERY_ANGLE            Z+      GetQueryivANGLE          0               active query ID          5.3
+    QUERY_RESULT_ANGLE             Z+      GetQueryObjectuivANGLE,  0               samples-passed count     5.3
+                                           GetQueryObjectui64vANGLE
+    QUERY_RESULT_AVAILABLE_ANGLE   B       GetQueryObjectivANGLE    FALSE           query result available   5.3
+
+New Implementation Dependent State
+
+    (Add the following entry to table 6.18):
+
+    Get Value                      Type    Get Command      Minimum Value      Description           Sec
+    --------------------------     ----    -----------      -------------      ----------------      ------
+    QUERY_COUNTER_BITS_ANGLE       Z+      GetQueryivANGLE  see 6.1.9          Number of bits in     6.1.9
+                                                                               query counter
+
+Examples
+
+    (1) Here is some rough sample code that demonstrates the intended usage
+        of this extension.
+
+        GLint queries[N];
+        GLint available = 0;
+        // timer queries can contain more than 32 bits of data, so always
+        // query them using the 64 bit types to avoid overflow
+        GLuint64ANGLE timeElapsed = 0;
+
+        // Create a query object.
+        glGenQueriesANGLE(N, queries);
+
+        // Start query 1
+        glBeginQueryANGLE(GL_TIME_ELAPSED_ANGLE, queries[0]);
+
+        // Draw object 1
+        ....
+
+        // End query 1
+        glEndQueryANGLE(GL_TIME_ELAPSED_ANGLE);
+
+        ...
+
+        // Start query N
+        glBeginQueryANGLE(GL_TIME_ELAPSED_ANGLE, queries[N-1]);
+
+        // Draw object N
+        ....
+
+        // End query N
+        glEndQueryANGLE(GL_TIME_ELAPSED_ANGLE);
+
+        // Wait for all results to become available
+        while (!available) {
+            glGetQueryObjectivANGLE(queries[N-1], GL_QUERY_RESULT_AVAILABLE_ANGLE, &available);
+        }
+
+        for (i = 0; i < N; i++) {
+            // See how much time the rendering of object i took in nanoseconds.
+            glGetQueryObjectui64vANGLE(queries[i], GL_QUERY_RESULT_ANGLE, &timeElapsed);
+
+            // Do something useful with the time.  Note that care should be
+            // taken to use all significant bits of the result, not just the
+            // least significant 32 bits.
+            AdjustObjectLODBasedOnDrawTime(i, timeElapsed);
+        }
+
+        This example is sub-optimal in that it stalls at the end of every
+        frame to wait for query results.  Ideally, the collection of results
+        would be delayed one frame to minimize the amount of time spent
+        waiting for the GPU to finish rendering.
+        
+    (2) This example is basically the same as the example above but uses
+        QueryCounter instead.
+    
+        GLint queries[N+1];
+        GLint available = 0;
+        // timer queries can contain more than 32 bits of data, so always
+        // query them using the 64 bit types to avoid overflow
+        GLuint64ANGLE timeStart, timeEnd, timeElapsed = 0;
+
+        // Create a query object.
+        glGenQueriesANGLE(N+1, queries);
+
+        // Query current timestamp 1
+        glQueryCounterANGLE(queries[0], GL_TIMESTAMP_ANGLE);
+
+        // Draw object 1
+        ....
+
+        // Query current timestamp N
+        glQueryCounterANGLE(queries[N-1], GL_TIMESTAMP_ANGLE);
+
+        // Draw object N
+        ....
+
+        // Query current timestamp N+1
+        glQueryCounterANGLE(queries[N], GL_TIMESTAMP_ANGLE);
+
+        // Wait for all results to become available
+        while (!available) {
+            glGetQueryObjectivANGLE(queries[N], GL_QUERY_RESULT_AVAILABLE_ANGLE, &available);
+        }
+
+        for (i = 0; i < N; i++) {
+            // See how much time the rendering of object i took in nanoseconds.
+            glGetQueryObjectui64vANGLE(queries[i], GL_QUERY_RESULT_ANGLE, &timeStart);
+            glGetQueryObjectui64vANGLE(queries[i+1], GL_QUERY_RESULT_ANGLE, &timeEnd);
+            timeElapsed = timeEnd - timeStart;
+
+            // Do something useful with the time.  Note that care should be
+            // taken to use all significant bits of the result, not just the
+            // least significant 32 bits.
+            AdjustObjectLODBasedOnDrawTime(i, timeElapsed);
+        }
+
+Issues from EXT_timer_query
+
+    (1) What time interval is being measured?
+
+    RESOLVED:  The timer starts when all commands prior to BeginQuery() have
+    been fully executed.  At that point, everything that should be drawn by
+    those commands has been written to the framebuffer.  The timer stops
+    when all commands prior to EndQuery() have been fully executed.
+
+    (2) What unit of time will time intervals be returned in?
+
+    RESOLVED:  Nanoseconds (10^-9 seconds).  This unit of measurement allows
+    for reasonably accurate timing of even small blocks of rendering
+    commands.  The granularity of the timer is implementation-dependent.  A
+    32-bit query counter can express intervals of up to approximately 4
+    seconds.
+
+    (3) What should be the minimum number of counter bits for timer queries?
+
+    RESOLVED:  30 bits, which will allow timing sections that take up to 1
+    second to render.
+
+    (4) How are counter results of more than 32 bits returned?
+
+    RESOLVED:  Via two new datatypes, int64ANGLE and uint64ANGLE, and their
+    corresponding GetQueryObject entry points.  These types hold integer
+    values and have a minimum bit width of 64.
+
+    (5) Should the extension measure total time elapsed between the full
+        completion of the BeginQuery and EndQuery commands, or just time
+        spent in the graphics library?
+
+    RESOLVED:  This extension will measure the total time elapsed between
+    the full completion of these commands.  Future extensions may implement
+    a query to determine time elapsed at different stages of the graphics
+    pipeline.
+
+    (6) If multiple query types are supported, can multiple query types be
+        active simultaneously?
+
+    RESOLVED:  Yes; an application may perform a timer query and another
+    type of query simultaneously.  An application can not perform multiple
+    timer queries or multiple queries of other types simultaneously.  An
+    application also can not use the same query object for another query
+    and a timer query simultaneously.
+
+    (7) Do query objects have a query type permanently associated with them?
+
+    RESOLVED:  No.  A single query object can be used to perform different
+    types of queries, but not at the same time.
+
+    Having a fixed type for each query object simplifies some aspects of the
+    implementation -- not having to deal with queries with different result
+    sizes, for example.  It would also mean that BeginQuery() with a query
+    object of the "wrong" type would result in an INVALID_OPERATION error.
+
+    UPDATE: This resolution was relevant for EXT_timer_query and OpenGL 2.0.
+    Since EXT_transform_feedback has since been incorporated into the core,
+    the resolution is that BeginQuery will generate error INVALID_OPERATION
+    if <id> represents a query object of a different type.
+
+    (8) How predictable/repeatable are the results returned by the timer
+        query?
+
+    RESOLVED:  In general, the amount of time needed to render the same
+    primitives should be fairly constant.  But there may be many other
+    system issues (e.g., context switching on the CPU and GPU, virtual
+    memory page faults, memory cache behavior on the CPU and GPU) that can
+    cause times to vary wildly.
+
+    Note that modern GPUs are generally highly pipelined, and may be
+    processing different primitives in different pipeline stages
+    simultaneously.  In this extension, the timers start and stop when the
+    BeginQuery/EndQuery commands reach the bottom of the rendering pipeline.
+    What that means is that by the time the timer starts, the GL driver on
+    the CPU may have started work on GL commands issued after BeginQuery,
+    and the higher pipeline stages (e.g., vertex transformation) may have
+    started as well.
+
+   (9) What should the new 64 bit integer type be called?
+
+    RESOLVED: The new types will be called GLint64ANGLE/GLuint64ANGLE.  The new
+    command suffixes will be i64 and ui64.  These names clearly convey the
+    minimum size of the types.  These types are similar to the C99 standard
+    type int_least64_t, but we use names similar to the C99 optional type
+    int64_t for simplicity.
+
+Issues from ARB_timer_query
+
+   (10) What about tile-based implementations? The effects of a command are
+        not complete until the frame is completely rendered. Timing recorded
+        before the frame is complete may not be what developers expect. Also
+        the amount of time needed to render the same primitives is not
+        consistent, which conflicts with issue (8) above. The time depends on
+        how early or late in the scene it is placed.
+
+    RESOLVED: The current language supports tile-based rendering okay as it
+    is written. Developers are warned that using timers on tile-based
+    implementation may not produce results they expect since rendering is not
+    done in a linear order. Timing results are calculated when the frame is
+    completed and may depend on how early or late in the scene it is placed.
+    
+   (11) Can the GL implementation use different clocks to implement the
+        TIME_ELAPSED and TIMESTAMP queries?
+
+   RESOLVED: Yes, the implemenation can use different internal clocks to
+   implement TIME_ELAPSED and TIMESTAMP. If different clocks are
+   used it is possible there is a slight discrepancy when comparing queries
+   made from TIME_ELAPSED and TIMESTAMP; they may have slight
+   differences when both are used to measure the same sequence. However, this
+   is unlikely to affect real applications since comparing the two queries is
+   not expected to be useful.
+
+Issues
+
+    (12) What should we call this extension?
+
+    RESOLVED: ANGLE_timer_query
+
+    (13) Why is this done as a separate extension instead of just supporting
+         ARB_timer_query?
+
+    ARB_timer_query is written against OpenGL 3.2, which includes a lot of
+    the required support for dealing with query objects. None of these
+    functions or tokens exist in OpenGL ES, and as such have to be added in
+    this specification.
+
+    (14) How does this extension differ from ARB_timer_query?
+
+    This extension contains most ARB_timer_query behavior unchanged as well
+    as a subset of the query support required to use it from the core
+    OpenGL 3.2 spec. It omits the glGetInteger(TIMESTAMP) functionality used to
+    query the current time on the GPU, but the behavior for all remaining
+    functionality taken from ARB_timer_query is the same.
+    
+    (15) Are query objects shareable between multiple contexts?
+
+    RESOLVED: No.  Query objects are lightweight and we normally share 
+    large data across contexts.  Also, being able to share query objects
+    across contexts is not particularly useful.  In order to do the async 
+    query across contexts, a query on one context would have to be finished 
+    before the other context could query it. 
+
+Revision History
+
+    Revision 1, 2011/04/28
+      - copied from revision 9 of ARB_timer_query and revision 7 of
+        ARB_occlusion_query
+      - removed language that was clearly not relevant to ES2
+      - rebased changes against the OpenGL ES 2.0 specification
new file mode 100644
--- /dev/null
+++ b/gfx/angle/extensions/EGL_ANGLE_d3d_share_handle_client_buffer.txt
@@ -0,0 +1,98 @@
+Name
+
+    ANGLE_d3d_share_handle_client_buffer
+
+Name Strings
+
+    EGL_ANGLE_d3d_share_handle_client_buffer
+
+Contributors
+
+    John Bauman
+    Alastair Patrick
+    Daniel Koch
+
+Contacts
+
+    John Bauman, Google Inc. (jbauman 'at' chromium.org)
+
+Status
+
+    Complete
+    Implemented (ANGLE r650)
+
+Version
+
+    Version 3, May 12, 2011
+
+Number
+
+    EGL Extension #??
+
+Dependencies
+
+    Requires the EGL_ANGLE_surface_d3d_texture_2d_share_handle extension.
+
+    This extension is written against the wording of the EGL 1.4
+    Specification.
+
+Overview
+
+    This extension allows creating EGL surfaces from handles to textures
+    shared from the Direct3D API or from
+    EGL_ANGLE_surface_texture_2d_share_handle.
+
+New Types
+
+    None
+
+New Procedures and Functions
+
+    None
+
+New Tokens
+
+    Accepted in the <buftype> parameter of eglCreatePbufferFromClientBuffer:
+
+        EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE            0x3200
+
+Additions to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors)
+
+    Replace the last sentence of paragraph 1 of Section 3.5.3 with the
+    following text.
+    "Currently, the only client API resources which may be bound in this
+    fashion are OpenVG VGImage objects and Direct3D share handles."
+
+    Replace the last sentence of paragraph 2 ("To bind a client API...") of
+    Section 3.5.3 with the following text.
+    "When <buftype> is EGL_OPENVG_IMAGE, the width and height of the pbuffer
+    are determined by the width and height of <buffer>. When <buftype> is
+    EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, the width and height are specified
+    using EGL_WIDTH and EGL_HEIGHT, or else they default to zero. The width
+    and height must match the dimensions of the texture which the share handle 
+    was created from or else an EGL_BAD_ALLOC error is generated."
+
+    Replace the third paragraph of Section 3.5.3 with the following text.
+    "<buftype> specifies the type of buffer to be bound. The only allowed values
+    of <buftype> are EGL_OPENVG_IMAGE and
+    EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE".
+
+    Append the following text to the fourth paragraph of Section 3.5.3.
+    "When <buftype> is EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, <buffer> must be
+    a valid D3D share handle, cast into the type EGLClientBuffer. The handle
+    may be obtained from the Direct3D9Ex CreateTexture function, from DXGI's
+    GetSharedHandle method on an ID3D10Texture2D, or from the
+    EGL_ANGLE_surface_d3d_texture_2d_share_handle extension."
+
+Issues
+
+Revision History
+
+    Version 3, 2011/05/12
+      - publish
+
+    Version 2, 2011/05/03
+      - specify EGL_D3D_TEXTURE_2D_SHARE_HANDLE
+      - specify error if dimensions don't match
+
+    Version 1, 2011/04/12 - first draft.
new file mode 100644
--- /dev/null
+++ b/gfx/angle/extensions/EGL_ANGLE_query_surface_pointer.txt
@@ -0,0 +1,88 @@
+Name
+
+    ANGLE_query_surface_pointer
+
+Name Strings
+
+    EGL_ANGLE_query_surface_pointer
+
+Contributors
+
+    Vladimir Vukicevic
+    Daniel Koch
+
+Contacts
+
+    Vladimir Vukicevic (vladimir 'at' pobox.com)
+
+Status
+
+    Complete
+    Implemented (ANGLE r558)
+
+Version
+
+    Version 3, February 11, 2011
+
+Number
+
+    EGL Extension #??
+
+Dependencies
+
+    This extension is written against the wording of the EGL 1.4
+    Specification. 
+
+Overview
+
+    This extension allows querying pointer-sized surface attributes,
+    thus avoiding problems with coercing 64-bit pointers into a 32-bit
+    integer.
+
+New Types
+
+    None
+
+New Procedures and Functions
+
+    EGLBoolean eglQuerySurfacePointerANGLE(
+                        EGLDisplay dpy,
+                        EGLSurface surface,
+                        EGLint attribute,
+                        void **value);
+
+New Tokens
+
+    None
+
+Additions to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors)
+
+    Add to the end of the paragraph starting with "To query an
+    attribute associated with an EGLSurface" in section 3.5.6,
+    "Surface Attributes":
+
+    "If the attribute type in table 3.5 is 'pointer', then
+    eglQuerySurface returns EGL_FALSE and an EGL_BAD_PARAMETER error
+    is generated.  To query pointer attributes, call:
+
+         EGLBoolean eglQuerySurfacePointerANGLE(
+                             EGLDisplay dpy,
+                             EGLSurface surface,
+                             EGLint attribute,
+                             void **value);
+
+     eglQuerySurfacePointerANGLE behaves identically to eglQuerySurface,
+     except that only attributes of type 'pointer' can be queried.
+     If an attribute queried via eglQuerySurfacePointerANGLE is not
+     of type 'pointer', then eglQuerySurfacePointer returns EGL_FALSE
+     and an EGL_BAD_PARAMETER error is generated."
+
+Issues
+
+Revision History
+
+    Version 3, 2011/02/11 - publish
+
+    Version 2, 2010/12/21 - fix typos.
+
+    Version 1, 2010/12/07 - first draft.
new file mode 100644
--- /dev/null
+++ b/gfx/angle/extensions/EGL_ANGLE_surface_d3d_texture_2d_share_handle.txt
@@ -0,0 +1,95 @@
+Name
+
+    ANGLE_surface_d3d_texture_2d_share_handle
+
+Name Strings
+
+    EGL_ANGLE_surface_d3d_texture_2d_share_handle
+
+Contributors
+
+    Vladimir Vukicevic
+    Daniel Koch
+
+Contacts
+
+    Vladimir Vukicevic (vladimir 'at' pobox.com)
+
+Status
+
+    Complete
+    Implemented (ANGLE r558)
+
+Version
+
+    Version 2, December 21, 2010
+
+Number
+
+    EGL Extension #??
+
+Dependencies
+
+    Requires the EGL_ANGLE_query_surface_pointer extension.
+
+    This extension is written against the wording of the EGL 1.4
+    Specification.
+
+Overview
+
+    Some EGL implementations generate EGLSurface handles that are
+    backed by Direct3D 2D textures.  For such surfaces, a D3D share
+    handle can be generated, allowing access to the same surface
+    from the Direct3D API.
+
+New Types
+
+    None
+
+New Procedures and Functions
+
+    None
+
+New Tokens
+
+    Accepted in the <attribute> parameter of eglQuerySurfacePointerANGLE:
+
+        EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE            0x3200
+
+Additions to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors)
+
+    Add to table 3.5, "Queryable surface attributes and types":
+
+        Attribute                              Type      Description
+        ---------                              ----      -----------
+        EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE  pointer   Direct3D share handle
+
+    Add before the last paragraph in section 3.5, "Surface attributes":
+
+   "Querying EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE returns a Direct3D
+    share handle, or NULL if a share handle for the surface is not
+    available.  The share handle must be queried using
+    eglQuerySurfaceAttribPointerANGLE.  Before using a Direct3D surface
+    created with this share handle, ensure that all rendering
+    to the EGLSurface with EGL client APIs has completed.
+
+    The Direct3D share handle may be passed as the pSharedHandle
+    parameter of the Direct3D9Ex CreateTexture function, or via the
+    Direct3D10 OpenSharedResource function.  If used with Direct3D 9,
+    the level argument to CreateTexture must be 1, and the dimensions
+    must match the dimensions of the EGL surface.  If used with
+    Direct3D 10, OpenSharedResource should be called with the
+    ID3D10Texture2D uuid to obtain an ID3D10Texture2D object.
+
+Issues
+
+Revision History
+
+    Version 3, 2011/02/11 - publish
+
+    Version 2, 2010/12/21
+      - renamed token to EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE (adding "2D")
+      - renamed extension to ANGLE_surface_d3d_texture_2d_share_handle
+      - added language about supported usage of the shared handle from D3D
+
+    Version 1, 2010/12/07 - first draft.
--- a/gfx/angle/include/EGL/eglext.h
+++ b/gfx/angle/include/EGL/eglext.h
@@ -218,18 +218,18 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLG
 #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_share_handle
-#define EGL_ANGLE_surface_d3d_share_handle
-#define EGL_D3D_TEXTURE_SHARE_HANDLE_ANGLE 0x3200
+#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
 #endif
 
 #ifdef __cplusplus
 }
 #endif
 
 #endif
--- 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 103
+#define SH_VERSION 104
 
 //
 // 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 {
@@ -57,28 +57,30 @@ typedef enum {
 } ShDataType;
 
 typedef enum {
   SH_INFO_LOG_LENGTH             =  0x8B84,
   SH_OBJECT_CODE_LENGTH          =  0x8B88,  // GL_SHADER_SOURCE_LENGTH
   SH_ACTIVE_UNIFORMS             =  0x8B86,
   SH_ACTIVE_UNIFORM_MAX_LENGTH   =  0x8B87,
   SH_ACTIVE_ATTRIBUTES           =  0x8B89,
-  SH_ACTIVE_ATTRIBUTE_MAX_LENGTH =  0x8B8A
+  SH_ACTIVE_ATTRIBUTE_MAX_LENGTH =  0x8B8A,
+  SH_MAPPED_NAME_MAX_LENGTH      =  0x8B8B
 } ShShaderInfo;
 
 // Compile options.
 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            = 0x0200
+  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
 } 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();
@@ -180,16 +182,18 @@ int ShCompile(
 // SH_ACTIVE_ATTRIBUTES: the number of active attribute variables.
 // SH_ACTIVE_ATTRIBUTE_MAX_LENGTH: the length of the longest active attribute
 //                                 variable name including the null
 //                                 termination character.
 // SH_ACTIVE_UNIFORMS: the number of active uniform variables.
 // SH_ACTIVE_UNIFORM_MAX_LENGTH: the length of the longest active uniform
 //                               variable name including the null
 //                               termination character.
+// SH_MAPPED_NAME_MAX_LENGTH: the length of the mapped variable name including
+//                            the null termination character.
 // 
 // params: Requested parameter
 void ShGetInfo(const ShHandle handle, ShShaderInfo pname, int* params);
 
 // Returns nul-terminated information log for a compiled shader.
 // Parameters:
 // handle: Specifies the compiler
 // infoLog: Specifies an array of characters that is used to return
@@ -218,41 +222,53 @@ void ShGetObjectCode(const ShHandle hand
 //         than NULL is passed.
 // size: Returns the size of the attribute variable.
 // type: Returns the data type of the attribute variable.
 // name: Returns a null terminated string containing the name of the
 //       attribute variable. It is assumed that name has enough memory to
 //       accomodate the attribute variable name. The size of the buffer
 //       required to store the attribute variable name can be obtained by
 //       calling ShGetInfo with SH_ACTIVE_ATTRIBUTE_MAX_LENGTH.
+// mappedName: Returns a null terminated string containing the mapped name of
+//             the attribute variable, It is assumed that mappedName has enough
+//             memory (SH_MAPPED_NAME_MAX_LENGTH), or NULL if don't care
+//             about the mapped name. If the name is not mapped, then name and
+//             mappedName are the same.
 void ShGetActiveAttrib(const ShHandle handle,
                        int index,
                        int* length,
                        int* size,
                        ShDataType* type,
-                       char* name);
+                       char* name,
+                       char* mappedName);
 
 // Returns information about an active uniform variable.
 // Parameters:
 // handle: Specifies the compiler
 // index: Specifies the index of the uniform variable to be queried.
 // length: Returns the number of characters actually written in the string
 //         indicated by name (excluding the null terminator) if a value
 //         other than NULL is passed.
 // size: Returns the size of the uniform variable.
 // type: Returns the data type of the uniform variable.
 // name: Returns a null terminated string containing the name of the
 //       uniform variable. It is assumed that name has enough memory to
 //       accomodate the uniform variable name. The size of the buffer required
 //       to store the uniform variable name can be obtained by calling
 //       ShGetInfo with SH_ACTIVE_UNIFORMS_MAX_LENGTH.
+// mappedName: Returns a null terminated string containing the mapped name of
+//             the uniform variable, It is assumed that mappedName has enough
+//             memory (SH_MAPPED_NAME_MAX_LENGTH), or NULL if don't care
+//             about the mapped name. If the name is not mapped, then name and
+//             mappedName are the same.
 void ShGetActiveUniform(const ShHandle handle,
                         int index,
                         int* length,
                         int* size,
                         ShDataType* type,
-                        char* name);
+                        char* name,
+                        char* mappedName);
 
 #ifdef __cplusplus
 }
 #endif
 
 #endif // _COMPILER_INTERFACE_INCLUDED_
--- a/gfx/angle/samples/translator/translator.cpp
+++ b/gfx/angle/samples/translator/translator.cpp
@@ -226,20 +226,20 @@ void PrintActiveVariables(ShHandle compi
 
     int activeVars = 0, size = 0;
     ShDataType type = SH_NONE;
     char* typeName = NULL;
     ShGetInfo(compiler, varType, &activeVars);
     for (int i = 0; i < activeVars; ++i) {
         switch (varType) {
             case SH_ACTIVE_ATTRIBUTES:
-                ShGetActiveAttrib(compiler, i, NULL, &size, &type, name);
+                ShGetActiveAttrib(compiler, i, NULL, &size, &type, name, NULL);
                 break;
             case SH_ACTIVE_UNIFORMS:
-                ShGetActiveUniform(compiler, i, NULL, &size, &type, name);
+                ShGetActiveUniform(compiler, i, NULL, &size, &type, name, NULL);
                 break;
             default: assert(0);
         }
         switch (type) {
             case SH_FLOAT: typeName = "GL_FLOAT"; break;
             case SH_FLOAT_VEC2: typeName = "GL_FLOAT_VEC2"; break;
             case SH_FLOAT_VEC3: typeName = "GL_FLOAT_VEC3"; break;
             case SH_FLOAT_VEC4: typeName = "GL_FLOAT_VEC4"; break;
--- a/gfx/angle/src/build_angle.gyp
+++ b/gfx/angle/src/build_angle.gyp
@@ -1,16 +1,17 @@
 # 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.
 
 {
   'target_defaults': {
     'defines': [
       'ANGLE_DISABLE_TRACE',
+      'ANGLE_COMPILE_OPTIMIZATION_LEVEL=D3DCOMPILE_OPTIMIZATION_LEVEL0',
     ],
   },
   'targets': [
     {
       'target_name': 'translator_common',
       'type': 'static_library',
       'include_dirs': [
         '.',
@@ -35,16 +36,18 @@
         'compiler/InitializeDll.h',
         'compiler/InitializeGlobals.h',
         'compiler/InitializeParseContext.h',
         'compiler/Intermediate.cpp',
         'compiler/intermediate.h',
         'compiler/intermOut.cpp',
         'compiler/IntermTraverse.cpp',
         'compiler/localintermediate.h',
+        'compiler/MapLongVariableNames.cpp',
+        'compiler/MapLongVariableNames.h',
         'compiler/MMap.h',
         'compiler/osinclude.h',
         'compiler/parseConst.cpp',
         'compiler/ParseHelper.cpp',
         'compiler/ParseHelper.h',
         'compiler/PoolAlloc.cpp',
         'compiler/PoolAlloc.h',
         'compiler/QualifierAlive.cpp',
@@ -94,16 +97,18 @@
       'type': 'static_library',
       'dependencies': ['translator_common'],
       'include_dirs': [
         '.',
         '../include',
       ],
       'sources': [
         'compiler/CodeGenGLSL.cpp',
+        'compiler/ForLoopUnroll.cpp',
+        'compiler/ForLoopUnroll.h',
         'compiler/OutputGLSL.cpp',
         'compiler/OutputGLSL.h',
         'compiler/TranslatorGLSL.cpp',
         'compiler/TranslatorGLSL.h',
         'compiler/VersionGLSL.cpp',
         'compiler/VersionGLSL.h',
       ],
     },
@@ -140,31 +145,33 @@
             '../include',
             '$(DXSDK_DIR)/include',
           ],
           'sources': [
             'common/angleutils.h',
             'common/debug.cpp',
             'common/debug.h',
             'common/version.h',
-            'libGLESv2/geometry/IndexDataManager.cpp',
-            'libGLESv2/geometry/IndexDataManager.h',
-            'libGLESv2/geometry/vertexconversion.h',
-            'libGLESv2/geometry/VertexDataManager.cpp',
-            'libGLESv2/geometry/VertexDataManager.h',
+            'libGLESv2/IndexDataManager.cpp',
+            'libGLESv2/IndexDataManager.h',
+            'libGLESv2/vertexconversion.h',
+            'libGLESv2/VertexDataManager.cpp',
+            'libGLESv2/VertexDataManager.h',
             'libGLESv2/Blit.cpp',
             'libGLESv2/Blit.h',
             'libGLESv2/Buffer.cpp',
             'libGLESv2/Buffer.h',
             'libGLESv2/Context.cpp',
             'libGLESv2/Context.h',
             '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/main.cpp',
             'libGLESv2/main.h',
             'libGLESv2/mathutil.h',
             'libGLESv2/Program.cpp',
             'libGLESv2/Program.h',
             'libGLESv2/RefCountObject.cpp',
@@ -181,16 +188,17 @@
             'libGLESv2/utilities.h',
           ],
           'msvs_settings': {
             'VCLinkerTool': {
               'AdditionalLibraryDirectories': ['$(DXSDK_DIR)/lib/x86'],
               'AdditionalDependencies': [
                 'd3d9.lib',
                 'd3dx9.lib',
+                'd3dcompiler.lib',
               ],
             }
           },
         },
         {
           'target_name': 'libEGL',
           'type': 'shared_library',
           'dependencies': ['libGLESv2'],
--- a/gfx/angle/src/common/debug.cpp
+++ b/gfx/angle/src/common/debug.cpp
@@ -67,17 +67,18 @@ void trace(bool traceFileDebugOnly, cons
     va_end(vararg);
 }
 
 bool perfActive()
 {
 #if defined(ANGLE_DISABLE_PERF)
     return false;
 #else
-    return D3DPERF_GetStatus() != 0;
+    static bool active = D3DPERF_GetStatus() != 0;
+    return active;
 #endif
 }
 
 ScopedPerfEventHelper::ScopedPerfEventHelper(const char* format, ...)
 {
     va_list vararg;
     va_start(vararg, format);
     output(true, reinterpret_cast<PerfOutputFunction>(D3DPERF_BeginEvent), format, vararg);
--- a/gfx/angle/src/common/debug.h
+++ b/gfx/angle/src/common/debug.h
@@ -58,17 +58,17 @@ namespace gl
 #else
 #define ERR(message, ...) gl::trace(false, "err: %s(%d): "message"\n", __FUNCTION__, __LINE__, __VA_ARGS__)
 #endif
 
 // A macro to log a performance event around a scope.
 #if defined(ANGLE_DISABLE_TRACE) && defined(ANGLE_DISABLE_PERF)
 #define EVENT(message, ...) (void(0))
 #else
-#define EVENT(message, ...) gl::ScopedPerfEventHelper scopedPerfEventHelper ## __LINE__("%s\n" message, __FUNCTION__, __VA_ARGS__);
+#define EVENT(message, ...) gl::ScopedPerfEventHelper scopedPerfEventHelper ## __LINE__(__FUNCTION__ message "\n", __VA_ARGS__);
 #endif
 
 // A macro asserting a condition and outputting failures to the debug log
 #if !defined(NDEBUG)
 #define ASSERT(expression) do { \
     if(!(expression)) \
         ERR("\t! Assert failed in %s(%d): "#expression"\n", __FUNCTION__, __LINE__); \
         assert(expression); \
--- 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 611
+#define BUILD_REVISION 653
 
 #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/Compiler.cpp
+++ b/gfx/angle/src/compiler/Compiler.cpp
@@ -3,16 +3,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 #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);
@@ -142,24 +143,30 @@ bool TCompiler::compile(const char* cons
         (parseContext.treeRoot != NULL);
     if (success) {
         TIntermNode* root = parseContext.treeRoot;
         success = intermediate.postProcess(root);
 
         if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING))
             success = validateLimitations(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 (compileOptions & SH_MAP_LONG_VARIABLE_NAMES)
+            mapLongVariableNames(root);
+
+        if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS))
+            collectAttribsUniforms(root);
+
         if (success && (compileOptions & SH_INTERMEDIATE_TREE))
             intermediate.outputTree(root);
 
         if (success && (compileOptions & SH_OBJECT_CODE))
             translate(root);
-
-        if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS))
-            collectAttribsUniforms(root);
     }
 
     // Cleanup memory.
     intermediate.remove(parseContext.treeRoot);
     // Ensure symbol table is returned to the built-in level,
     // throwing away all but the built-ins.
     while (!symbolTable.atBuiltInLevel())
         symbolTable.pop();
@@ -192,8 +199,19 @@ bool TCompiler::validateLimitations(TInt
     return validate.numErrors() == 0;
 }
 
 void TCompiler::collectAttribsUniforms(TIntermNode* root)
 {
     CollectAttribsUniforms collect(attribs, uniforms);
     root->traverse(&collect);
 }
+
+void TCompiler::mapLongVariableNames(TIntermNode* root)
+{
+    MapLongVariableNames map;
+    root->traverse(&map);
+}
+
+int TCompiler::getMappedNameMaxLength() const
+{
+    return MAX_IDENTIFIER_NAME_SIZE + 1;
+}
--- a/gfx/angle/src/compiler/ConstantUnion.h
+++ b/gfx/angle/src/compiler/ConstantUnion.h
@@ -21,59 +21,43 @@ public:
     float getFConst() { return fConst; }
     bool getBConst() { return bConst; }
     int getIConst() const { return iConst; }
     float getFConst() const { return fConst; }
     bool getBConst() const { return bConst; }
 
     bool operator==(const int i) const
     {
-        if (i == iConst)
-            return true;
-
-        return false;
+        return i == iConst;
     }
 
     bool operator==(const float f) const
     {
-        if (f == fConst)
-            return true;
-
-        return false;
+        return f == fConst;
     }
 
     bool operator==(const bool b) const
     {
-        if (b == bConst)
-            return true;
-
-        return false;
+        return b == bConst;
     }
 
     bool operator==(const ConstantUnion& constant) const
     {
         if (constant.type != type)
             return false;
 
         switch (type) {
         case EbtInt:
-            if (constant.iConst == iConst)
-                return true;
-
-            break;
+            return constant.iConst == iConst;
         case EbtFloat:
-            if (constant.fConst == fConst)
-                return true;
-
-            break;
+            return constant.fConst == fConst;
         case EbtBool:
-            if (constant.bConst == bConst)
-                return true;
-
-            break;
+            return constant.bConst == bConst;
+        default:
+            return false;
         }
 
         return false;
     }
 
     bool operator!=(const int i) const
     {
         return !operator==(i);
@@ -94,50 +78,36 @@ public:
         return !operator==(constant);
     }
 
     bool operator>(const ConstantUnion& constant) const
     { 
         assert(type == constant.type);
         switch (type) {
         case EbtInt:
-            if (iConst > constant.iConst)
-                return true;
-
-            return false;
+            return iConst > constant.iConst;
         case EbtFloat:
-            if (fConst > constant.fConst)
-                return true;
-
-            return false;
+            return fConst > constant.fConst;
         default:
-            assert(false && "Default missing");
-            return false;
+            return false;   // Invalid operation, handled at semantic analysis
         }
 
         return false;
     }
 
     bool operator<(const ConstantUnion& constant) const
     { 
         assert(type == constant.type);
         switch (type) {
         case EbtInt:
-            if (iConst < constant.iConst)
-                return true;
-
-            return false;
+            return iConst < constant.iConst;
         case EbtFloat:
-            if (fConst < constant.fConst)
-                return true;
-
-            return false;
+            return fConst < constant.fConst;
         default:
-            assert(false && "Default missing");
-            return false;
+            return false;   // Invalid operation, handled at semantic analysis
         }
 
         return false;
     }
 
     ConstantUnion operator+(const ConstantUnion& constant) const
     { 
         ConstantUnion returnValue;
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/ForLoopUnroll.cpp
@@ -0,0 +1,172 @@
+//
+// 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"
+
+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();
+    ASSERT((decl != NULL) && (decl->getOp() == EOpDeclaration));
+    TIntermSequence& declSeq = decl->getSequence();
+    ASSERT(declSeq.size() == 1);
+    TIntermBinary* declInit = declSeq[0]->getAsBinaryNode();
+    ASSERT((declInit != NULL) && (declInit->getOp() == EOpInitialize));
+    TIntermSymbol* symbol = declInit->getLeft()->getAsSymbolNode();
+    ASSERT(symbol != NULL);
+    ASSERT(symbol->getBasicType() == EbtInt);
+
+    info.id = symbol->getId();
+
+    ASSERT(declInit->getRight() != NULL);
+    TIntermConstantUnion* initNode = declInit->getRight()->getAsConstantUnion();
+    ASSERT(initNode != NULL);
+
+    info.initValue = evaluateIntConstant(initNode);
+    info.currentValue = info.initValue;
+
+    TIntermNode* cond = node->getCondition();
+    ASSERT(cond != NULL);
+    TIntermBinary* binOp = cond->getAsBinaryNode();
+    ASSERT(binOp != NULL);
+    ASSERT(binOp->getRight() != NULL);
+    ASSERT(binOp->getRight()->getAsConstantUnion() != NULL);
+
+    info.incrementValue = getLoopIncrement(node);
+    info.stopValue = evaluateIntConstant(
+        binOp->getRight()->getAsConstantUnion());
+    info.op = binOp->getOp();
+}
+
+void ForLoopUnroll::Step()
+{
+    ASSERT(mLoopIndexStack.size() > 0);
+    TLoopIndexInfo& info = mLoopIndexStack[mLoopIndexStack.size() - 1];
+    info.currentValue += info.incrementValue;
+}
+
+bool ForLoopUnroll::SatisfiesLoopCondition()
+{
+    ASSERT(mLoopIndexStack.size() > 0);
+    TLoopIndexInfo& info = mLoopIndexStack[mLoopIndexStack.size() - 1];
+    // Relational operator is one of: > >= < <= == or !=.
+    switch (info.op) {
+      case EOpEqual:
+        return (info.currentValue == info.stopValue);
+      case EOpNotEqual:
+        return (info.currentValue != info.stopValue);
+      case EOpLessThan:
+        return (info.currentValue < info.stopValue);
+      case EOpGreaterThan:
+        return (info.currentValue > info.stopValue);
+      case EOpLessThanEqual:
+        return (info.currentValue <= info.stopValue);
+      case EOpGreaterThanEqual:
+        return (info.currentValue >= info.stopValue);
+      default:
+        UNREACHABLE();
+    }
+    return false;
+}
+
+bool ForLoopUnroll::NeedsToReplaceSymbolWithValue(TIntermSymbol* symbol)
+{
+    for (TVector<TLoopIndexInfo>::iterator i = mLoopIndexStack.begin();
+         i != mLoopIndexStack.end();
+         ++i) {
+        if (i->id == symbol->getId())
+            return true;
+    }
+    return false;
+}
+
+int ForLoopUnroll::GetLoopIndexValue(TIntermSymbol* symbol)
+{
+    for (TVector<TLoopIndexInfo>::iterator i = mLoopIndexStack.begin();
+         i != mLoopIndexStack.end();
+         ++i) {
+        if (i->id == symbol->getId())
+            return i->currentValue;
+    }
+    UNREACHABLE();
+    return false;
+}
+
+void ForLoopUnroll::Push(TLoopIndexInfo& info)
+{
+    mLoopIndexStack.push_back(info);
+}
+
+void ForLoopUnroll::Pop()
+{
+    mLoopIndexStack.pop_back();
+}
+
+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
+    //     loop_index -= constant_expression
+    //     ++loop_index
+    //     --loop_index
+    // The last two forms are not specified in the spec, but I am assuming
+    // its an oversight.
+    TIntermUnary* unOp = expr->getAsUnaryNode();
+    TIntermBinary* binOp = unOp ? NULL : expr->getAsBinaryNode();
+
+    TOperator op = EOpNull;
+    TIntermConstantUnion* incrementNode = NULL;
+    if (unOp != NULL) {
+        op = unOp->getOp();
+    } else if (binOp != NULL) {
+        op = binOp->getOp();
+        ASSERT(binOp->getRight() != NULL);
+        incrementNode = binOp->getRight()->getAsConstantUnion();
+        ASSERT(incrementNode != NULL);
+    }
+
+    int increment = 0;
+    // The operator is one of: ++ -- += -=.
+    switch (op) {
+        case EOpPostIncrement:
+        case EOpPreIncrement:
+            ASSERT((unOp != NULL) && (binOp == NULL));
+            increment = 1;
+            break;
+        case EOpPostDecrement:
+        case EOpPreDecrement:
+            ASSERT((unOp != NULL) && (binOp == NULL));
+            increment = -1;
+            break;
+        case EOpAddAssign:
+            ASSERT((unOp == NULL) && (binOp != NULL));
+            increment = evaluateIntConstant(incrementNode);
+            break;
+        case EOpSubAssign:
+            ASSERT((unOp == NULL) && (binOp != NULL));
+            increment = - evaluateIntConstant(incrementNode);
+            break;
+        default:
+            ASSERT(false);
+    }
+
+    return increment;
+}
+
+int ForLoopUnroll::evaluateIntConstant(TIntermConstantUnion* node)
+{
+    ASSERT((node != NULL) && (node->getUnionArrayPointer() != NULL));
+    return node->getUnionArrayPointer()->getIConst();
+}
+
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/ForLoopUnroll.h
@@ -0,0 +1,46 @@
+//
+// 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.
+//
+
+#include "compiler/intermediate.h"
+
+struct TLoopIndexInfo {
+    int id;
+    int initValue;
+    int stopValue;
+    int incrementValue;
+    TOperator op;
+    int currentValue;
+};
+
+class ForLoopUnroll {
+public:
+    ForLoopUnroll() { }
+
+    void FillLoopIndexInfo(TIntermLoop* node, TLoopIndexInfo& info);
+
+    // Update the info.currentValue for the next loop iteration.
+    void Step();
+
+    // Return false if loop condition is no longer satisfied.
+    bool SatisfiesLoopCondition();
+
+    // Check if the symbol is the index of a loop that's unrolled.
+    bool NeedsToReplaceSymbolWithValue(TIntermSymbol* symbol);
+
+    // Return the current value of a given loop index symbol.
+    int GetLoopIndexValue(TIntermSymbol* symbol);
+
+    void Push(TLoopIndexInfo& info);
+    void Pop();
+
+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
@@ -348,27 +348,25 @@ static TString BuiltInFunctionsVertex(co
     //
     // Geometric Functions.
     //
     //s.append(TString("vec4 ftransform();"));
 
     //
     // Texture Functions.
     //
-    if (resources.MaxVertexTextureImageUnits > 0) {
-        s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord);"));
-        s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord);"));
-        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);"));
+    s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord);"));
+    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);"));
-    }
+    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);"));
 
     return s;
 }
 
 //============================================================================
 //
 // Prototypes for built-in functions seen by fragment shaders only.
 //
--- a/gfx/angle/src/compiler/Intermediate.cpp
+++ b/gfx/angle/src/compiler/Intermediate.cpp
@@ -1000,30 +1000,30 @@ bool TIntermBinary::promote(TInfoSink& i
         case EOpAssign:
         case EOpInitialize:
         case EOpAdd:
         case EOpSub:
         case EOpDiv:
         case EOpAddAssign:
         case EOpSubAssign:
         case EOpDivAssign:
-            if (left->isMatrix() && right->isVector() ||
-                left->isVector() && right->isMatrix())
+            if ((left->isMatrix() && right->isVector()) ||
+                (left->isVector() && right->isMatrix()))
                 return false;
             setType(TType(basicType, higherPrecision, EvqTemporary, size, left->isMatrix() || right->isMatrix()));
             break;
 
         case EOpEqual:
         case EOpNotEqual:
         case EOpLessThan:
         case EOpGreaterThan:
         case EOpLessThanEqual:
         case EOpGreaterThanEqual:
-            if (left->isMatrix() && right->isVector() ||
-                left->isVector() && right->isMatrix())
+            if ((left->isMatrix() && right->isVector()) ||
+                (left->isVector() && right->isMatrix()))
                 return false;
             setType(TType(EbtBool, EbpUndefined));
             break;
 
         default:
             return false;
     }
     
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/MapLongVariableNames.cpp
@@ -0,0 +1,61 @@
+//
+// 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/MapLongVariableNames.h"
+
+namespace {
+
+TString mapLongName(int id, const TString& name)
+{
+    ASSERT(name.size() > MAX_IDENTIFIER_NAME_SIZE);
+    TStringStream stream;
+    stream << "webgl_" << id << "_";
+    stream << name.substr(0, MAX_IDENTIFIER_NAME_SIZE - stream.str().size());
+    return stream.str();
+}
+
+}  // anonymous namespace
+
+void MapLongVariableNames::visitSymbol(TIntermSymbol* symbol)
+{
+    ASSERT(symbol != NULL);
+    if (symbol->getSymbol().size() > MAX_IDENTIFIER_NAME_SIZE)
+        symbol->setSymbol(mapLongName(symbol->getId(), symbol->getSymbol()));
+}
+
+void MapLongVariableNames::visitConstantUnion(TIntermConstantUnion*)
+{
+}
+
+bool MapLongVariableNames::visitBinary(Visit, TIntermBinary*)
+{
+    return true;
+}
+
+bool MapLongVariableNames::visitUnary(Visit, TIntermUnary*)
+{
+    return true;
+}
+
+bool MapLongVariableNames::visitSelection(Visit, TIntermSelection*)
+{
+    return true;
+}
+
+bool MapLongVariableNames::visitAggregate(Visit, TIntermAggregate* node)
+{
+    return true;
+}
+
+bool MapLongVariableNames::visitLoop(Visit, TIntermLoop*)
+{
+    return true;
+}
+
+bool MapLongVariableNames::visitBranch(Visit, TIntermBranch*)
+{
+    return true;
+}
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/MapLongVariableNames.h
@@ -0,0 +1,34 @@
+//
+// 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_MAP_LONG_VARIABLE_NAMES_H_
+#define COMPILER_MAP_LONG_VARIABLE_NAMES_H_
+
+#include "GLSLANG/ShaderLang.h"
+
+#include "compiler/intermediate.h"
+#include "compiler/VariableInfo.h"
+
+// This size does not include '\0' in the end.
+#define MAX_IDENTIFIER_NAME_SIZE 32
+
+// 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() { }
+
+    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*);
+};
+
+#endif  // COMPILER_MAP_LONG_VARIABLE_NAMES_H_
--- a/gfx/angle/src/compiler/OutputGLSL.cpp
+++ b/gfx/angle/src/compiler/OutputGLSL.cpp
@@ -1,10 +1,10 @@
 //
-// 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.
 //
 
 #include "compiler/OutputGLSL.h"
 #include "compiler/compilerdebug.h"
 
 namespace
@@ -190,17 +190,20 @@ const ConstantUnion* TOutputGLSL::writeC
         if (writeType) out << ")";
     }
     return pConstUnion;
 }
 
 void TOutputGLSL::visitSymbol(TIntermSymbol* node)
 {
     TInfoSinkBase& out = objSink();
-    out << node->getSymbol();
+    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());
@@ -610,44 +613,61 @@ bool TOutputGLSL::visitLoop(Visit visit,
 {
     TInfoSinkBase& out = objSink();
 
     incrementDepth();
     // Loop header.
     TLoopType loopType = node->getType();
     if (loopType == ELoopFor)  // for loop
     {
-        out << "for (";
-        if (node->getInit())
-            node->getInit()->traverse(this);
-        out << "; ";
+        if (!node->getUnrollFlag()) {
+            out << "for (";
+            if (node->getInit())
+                node->getInit()->traverse(this);
+            out << "; ";
 
-        if (node->getCondition())
-            node->getCondition()->traverse(this);
-        out << "; ";
+            if (node->getCondition())
+                node->getCondition()->traverse(this);
+            out << "; ";
 
-        if (node->getExpression())
-            node->getExpression()->traverse(this);
-        out << ")\n";
+            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.
-    visitCodeBlock(node->getBody());
+    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";
--- a/gfx/angle/src/compiler/OutputGLSL.h
+++ b/gfx/angle/src/compiler/OutputGLSL.h
@@ -4,16 +4,17 @@
 // found in the LICENSE file.
 //
 
 #ifndef CROSSCOMPILERGLSL_OUTPUTGLSL_H_
 #define CROSSCOMPILERGLSL_OUTPUTGLSL_H_
 
 #include <set>
 
+#include "compiler/ForLoopUnroll.h"
 #include "compiler/intermediate.h"
 #include "compiler/ParseHelper.h"
 
 class TOutputGLSL : public TIntermTraverser
 {
 public:
     TOutputGLSL(TInfoSinkBase& objSink);
 
@@ -39,11 +40,13 @@ 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_OUTPUTGLSL_H_
--- a/gfx/angle/src/compiler/OutputHLSL.cpp
+++ b/gfx/angle/src/compiler/OutputHLSL.cpp
@@ -1,10 +1,10 @@
 //
-// 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.
 //
 
 #include "compiler/OutputHLSL.h"
 
 #include "compiler/compilerdebug.h"
 #include "compiler/InfoSink.h"
@@ -28,18 +28,21 @@ OutputHLSL::OutputHLSL(TParseContext &co
 {
     mUnfoldSelect = new UnfoldSelect(context, this);
     mInsideFunction = false;
 
     mUsesTexture2D = false;
     mUsesTexture2D_bias = false;
     mUsesTexture2DProj = false;
     mUsesTexture2DProj_bias = false;
+    mUsesTexture2DProjLod = false;
+    mUsesTexture2DLod = false;
     mUsesTextureCube = false;
     mUsesTextureCube_bias = false;
+    mUsesTextureCubeLod = false;
     mUsesDepthRange = false;
     mUsesFragCoord = false;
     mUsesPointCoord = false;
     mUsesFrontFacing = false;
     mUsesPointSize = false;
     mUsesXor = false;
     mUsesMod1 = false;
     mUsesMod2 = false;
@@ -340,16 +343,94 @@ void OutputHLSL::header()
         out << "\n"
                "// Varyings\n";
         out <<  varyings;
         out << "\n"
                "uniform float2 dx_HalfPixelSize;\n"
                "\n";
         out <<  uniforms;
         out << "\n";
+
+        // The texture fetch functions "flip" the Y coordinate in one way or another. This is because textures are stored
+        // according to the OpenGL convention, i.e. (0, 0) is "bottom left", rather than the D3D convention where (0, 0)
+        // is "top left". Since the HLSL texture fetch functions expect textures to be stored according to the D3D
+        // convention, the Y coordinate passed to these functions is adjusted to compensate.
+        //
+        // The simplest case is texture2D where the mapping is Y -> 1-Y, which maps [0, 1] -> [1, 0].
+        //
+        // The texture2DProj functions are more complicated because the projection divides by either Z or W. For the vec3
+        // case, the mapping is Y -> Z-Y or Y/Z -> 1-Y/Z, which again maps [0, 1] -> [1, 0].
+        //
+        // For cube textures the mapping is Y -> -Y, which maps [-1, 1] -> [1, -1]. This is not sufficient on its own for the
+        // +Y and -Y faces, which are now on the "wrong sides" of the cube. This is compensated for by exchanging the
+        // +Y and -Y faces everywhere else throughout the code.
+        
+        if (mUsesTexture2D)
+        {
+            out << "float4 gl_texture2D(sampler2D s, float2 t)\n"
+                   "{\n"
+                   "    return tex2Dlod(s, float4(t.x, 1 - t.y, 0, 0));\n"
+                   "}\n"
+                   "\n";
+        }
+
+        if (mUsesTexture2DLod)
+        {
+            out << "float4 gl_texture2DLod(sampler2D s, float2 t, float lod)\n"
+                   "{\n"
+                   "    return tex2Dlod(s, float4(t.x, 1 - t.y, 0, lod));\n"
+                   "}\n"
+                   "\n";
+        }
+
+        if (mUsesTexture2DProj)
+        {
+            out << "float4 gl_texture2DProj(sampler2D s, float3 t)\n"
+                   "{\n"
+                   "    return tex2Dlod(s, float4(t.x / t.z, 1 - t.y / t.z, 0, 0));\n"
+                   "}\n"
+                   "\n"
+                   "float4 gl_texture2DProj(sampler2D s, float4 t)\n"
+                   "{\n"
+                   "    return tex2Dlod(s, float4(t.x / t.w, 1 - t.y / t.w, 0, 0));\n"
+                   "}\n"
+                   "\n";
+        }
+
+        if (mUsesTexture2DProjLod)
+        {
+            out << "float4 gl_texture2DProjLod(sampler2D s, float3 t, float lod)\n"
+                   "{\n"
+                   "    return tex2Dlod(s, float4(t.x / t.z, 1 - t.y / t.z, 0, lod));\n"
+                   "}\n"
+                   "\n"
+                   "float4 gl_texture2DProjLod(sampler2D s, float4 t, float lod)\n"
+                   "{\n"
+                   "    return tex2Dlod(s, float4(t.x / t.w, 1 - t.y / t.w, 0, lod));\n"
+                   "}\n"
+                   "\n";
+        }
+
+        if (mUsesTextureCube)
+        {
+            out << "float4 gl_textureCube(samplerCUBE s, float3 t)\n"
+                   "{\n"
+                   "    return texCUBElod(s, float4(t.x, -t.y, t.z, 0));\n"
+                   "}\n"
+                   "\n";
+        }
+
+        if (mUsesTextureCubeLod)
+        {
+            out << "float4 gl_textureCubeLod(samplerCUBE s, float3 t, float lod)\n"
+                   "{\n"
+                   "    return texCUBElod(s, float4(t.x, -t.y, t.z, lod));\n"
+                   "}\n"
+                   "\n";
+        }
     }
 
     if (mUsesFragCoord)
     {
         out << "#define GL_USES_FRAG_COORD\n";
     }
 
     if (mUsesPointCoord)
@@ -1242,25 +1323,43 @@ bool OutputHLSL::visitAggregate(Visit vi
                             mUsesTextureCube_bias = true;
                         }
                         else UNREACHABLE();
 
                         out << "gl_textureCube(";
                     }
                     else if (name == "texture2DLod")
                     {
-                        UNIMPLEMENTED();   // Requires the vertex shader texture sampling extension
+                        if (node->getSequence().size() == 3)
+                        {
+                            mUsesTexture2DLod = true;
+                        }
+                        else UNREACHABLE();
+
+                        out << "gl_texture2DLod(";
                     }
                     else if (name == "texture2DProjLod")
                     {
-                        UNIMPLEMENTED();   // Requires the vertex shader texture sampling extension
+                        if (node->getSequence().size() == 3)
+                        {
+                            mUsesTexture2DProjLod = true;
+                        }
+                        else UNREACHABLE();
+
+                        out << "gl_texture2DProjLod(";
                     }
                     else if (name == "textureCubeLod")
                     {
-                        UNIMPLEMENTED();   // Requires the vertex shader texture sampling extension
+                        if (node->getSequence().size() == 3)
+                        {
+                            mUsesTextureCubeLod = true;
+                        }
+                        else UNREACHABLE();
+
+                        out << "gl_textureCubeLod(";
                     }
                     else UNREACHABLE();
                 }
             }
             else if (visit == InVisit)
             {
                 out << ", ";
             }
@@ -1529,19 +1628,19 @@ bool OutputHLSL::visitLoop(Visit visit, 
 }
 
 bool OutputHLSL::visitBranch(Visit visit, TIntermBranch *node)
 {
     TInfoSinkBase &out = mBody;
 
     switch (node->getFlowOp())
     {
-      case EOpKill:     outputTriplet(visit, "discard", "", "");  break;
-      case EOpBreak:    outputTriplet(visit, "break", "", "");    break;
-      case EOpContinue: outputTriplet(visit, "continue", "", ""); break;
+      case EOpKill:     outputTriplet(visit, "discard;\n", "", "");  break;
+      case EOpBreak:    outputTriplet(visit, "break;\n", "", "");    break;
+      case EOpContinue: outputTriplet(visit, "continue;\n", "", ""); break;
       case EOpReturn:
         if (visit == PreVisit)
         {
             if (node->getExpression())
             {
                 out << "return ";
             }
             else
@@ -1701,27 +1800,27 @@ bool OutputHLSL::handleExcessiveLoop(TIn
         if (comparator == EOpLessThanEqual)
         {
             comparator = EOpLessThan;
             limit += 1;
         }
 
         if (comparator == EOpLessThan)
         {
-            int iterations = (limit - initial + 1) / increment;
+            int iterations = (limit - initial) / increment;
 
             if (iterations <= 255)
             {
                 return false;   // Not an excessive loop
             }
 
             while (iterations > 0)
             {
-                int remainder = (limit - initial + 1) % increment;
-                int clampedLimit = initial + increment * std::min(255, iterations) - 1 - remainder;
+                int remainder = (limit - initial) % increment;
+                int clampedLimit = initial + increment * std::min(255, iterations);
 
                 // for(int index = initial; index < clampedLimit; index += increment)
 
                 out << "for(int ";
                 index->traverse(this);
                 out << " = ";
                 out << initial;
 
--- a/gfx/angle/src/compiler/OutputHLSL.h
+++ b/gfx/angle/src/compiler/OutputHLSL.h
@@ -1,10 +1,10 @@
 //
-// 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 COMPILER_OUTPUTHLSL_H_
 #define COMPILER_OUTPUTHLSL_H_
 
 #include <list>
@@ -71,20 +71,23 @@ class OutputHLSL : public TIntermTravers
 
     std::set<std::string> mReferencedUniforms;
     std::set<std::string> mReferencedAttributes;
     std::set<std::string> mReferencedVaryings;
 
     // Parameters determining what goes in the header output
     bool mUsesTexture2D;
     bool mUsesTexture2D_bias;
+    bool mUsesTexture2DLod;
     bool mUsesTexture2DProj;
     bool mUsesTexture2DProj_bias;
+    bool mUsesTexture2DProjLod;
     bool mUsesTextureCube;
     bool mUsesTextureCube_bias;
+    bool mUsesTextureCubeLod;
     bool mUsesDepthRange;
     bool mUsesFragCoord;
     bool mUsesPointCoord;
     bool mUsesFrontFacing;
     bool mUsesPointSize;
     bool mUsesXor;
     bool mUsesMod1;
     bool mUsesMod2;
--- a/gfx/angle/src/compiler/ParseHelper.cpp
+++ b/gfx/angle/src/compiler/ParseHelper.cpp
@@ -269,16 +269,18 @@ bool TParseContext::precisionErrorCheck(
         }
         break;
     case EbtInt:
         if( precision == EbpUndefined ){
             error( line, "No precision specified (int)", "", "" );
             return true;
         }
         break;
+    default:
+        return false;
     }
     return false;
 }
 
 //
 // Both test and if necessary, spit out an error, to see if the node is really
 // an l-value that can be operated on this way.
 //
@@ -553,17 +555,17 @@ bool TParseContext::constructorErrorChec
     if (!type->isMatrix()) {
         if ((op != EOpConstructStruct && size != 1 && size < type->getObjectSize()) ||
             (op == EOpConstructStruct && size < type->getObjectSize())) {
             error(line, "not enough data provided for construction", "constructor", "");
             return true;
         }
     }
 
-    TIntermTyped* typed = node->getAsTyped();
+    TIntermTyped *typed = node ? node->getAsTyped() : 0;
     if (typed == 0) {
         error(line, "constructor argument does not have a type", "constructor", "");
         return true;
     }
     if (op != EOpConstructStruct && IsSampler(typed->getBasicType())) {
         error(line, "cannot convert a sampler", "constructor", "");
         return true;
     }
@@ -875,26 +877,27 @@ bool TParseContext::nonInitConstErrorChe
 }
 
 //
 // Do semantic checking for a variable declaration that has no initializer,
 // and update the symbol table.
 //
 // Returns true if there was an error.
 //
-bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType& type)
+bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType& type, TVariable*& variable)
 {
     if (reservedErrorCheck(line, identifier))
         recover();
 
-    TVariable* variable = new TVariable(&identifier, TType(type));
+    variable = new TVariable(&identifier, TType(type));
 
     if (! symbolTable.insert(*variable)) {
         error(line, "redefinition", variable->getName().c_str(), "");
         delete variable;
+        variable = 0;
         return true;
     }
 
     if (voidErrorCheck(line, identifier, type))
         return true;
 
     return false;
 }
--- a/gfx/angle/src/compiler/ParseHelper.h
+++ b/gfx/angle/src/compiler/ParseHelper.h
@@ -76,17 +76,17 @@ struct TParseContext {
     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);
+    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&);
     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);
     TIntermTyped* addConstructor(TIntermNode*, const TType*, TOperator, TFunction*, TSourceLoc);
     TIntermTyped* foldConstConstructor(TIntermAggregate* aggrNode, const TType& type);
--- a/gfx/angle/src/compiler/PoolAlloc.cpp
+++ b/gfx/angle/src/compiler/PoolAlloc.cpp
@@ -146,26 +146,28 @@ const unsigned char TAllocation::userDat
     const size_t TAllocation::guardBlockSize = 0;
 #endif
 
 //
 // Check a single guard block for damage
 //
 void TAllocation::checkGuardBlock(unsigned char* blockMem, unsigned char val, const char* locText) const
 {
+#ifdef GUARD_BLOCKS
     for (size_t x = 0; x < guardBlockSize; x++) {
         if (blockMem[x] != val) {
             char assertMsg[80];
 
             // We don't print the assert message.  It's here just to be helpful.
-            sprintf(assertMsg, "PoolAlloc: Damage %s %u byte allocation at 0x%p\n",
+            sprintf(assertMsg, "PoolAlloc: Damage %s %lu byte allocation at 0x%p\n",
                     locText, size, data());
             assert(0 && "PoolAlloc: Damage in guard block");
         }
     }
+#endif
 }
 
 
 void TPoolAllocator::push()
 {
     tAllocState state = { currentPageOffset, inUseList };
 
     stack.push_back(state);
@@ -294,9 +296,9 @@ void* TPoolAllocator::allocate(size_t nu
 
 //
 // Check all allocations in a list for damage by calling check on each.
 //
 void TAllocation::checkAllocList() const
 {
     for (const TAllocation* alloc = this; alloc != 0; alloc = alloc->prevAlloc)
         alloc->check();
-}
\ No newline at end of file
+}
--- a/gfx/angle/src/compiler/PoolAlloc.h
+++ b/gfx/angle/src/compiler/PoolAlloc.h
@@ -292,9 +292,9 @@ public:
 
     void setAllocator(TPoolAllocator* a) { allocator = *a; }
     TPoolAllocator& getAllocator() const { return allocator; }
 
 protected:
     TPoolAllocator& allocator;
 };
 
-#endif // _POOLALLOC_INCLUDED_
\ No newline at end of file
+#endif // _POOLALLOC_INCLUDED_
--- a/gfx/angle/src/compiler/ShHandle.h
+++ b/gfx/angle/src/compiler/ShHandle.h
@@ -52,29 +52,32 @@ public:
     bool compile(const char* const shaderStrings[],
                  const int numStrings,
                  int compileOptions);
 
     // Get results of the last compilation.
     TInfoSink& getInfoSink() { return infoSink; }
     const TVariableInfoList& getAttribs() const { return attribs; }
     const TVariableInfoList& getUniforms() const { return uniforms; }
+    int getMappedNameMaxLength() const;
 
 protected:
     ShShaderType getShaderType() const { return shaderType; }
     ShShaderSpec getShaderSpec() const { return shaderSpec; }
     // Initialize symbol-table with built-in symbols.
     bool InitBuiltInSymbolTable(const ShBuiltInResources& resources);
     // Clears the results from the previous compilation.
     void clearResults();
     // Returns true if the given shader does not exceed the minimum
     // 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;
 
 private:
     ShShaderType shaderType;
     ShShaderSpec shaderSpec;
 
     // Built-in symbol table for the given language, spec, and resources.
@@ -96,9 +99,9 @@ private:
 // 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);
 void DeleteCompiler(TCompiler*);
 
-#endif // _SHHANDLE_INCLUDED_
\ No newline at end of file
+#endif // _SHHANDLE_INCLUDED_
--- a/gfx/angle/src/compiler/ShaderLang.cpp
+++ b/gfx/angle/src/compiler/ShaderLang.cpp
@@ -32,17 +32,18 @@ static int getVariableMaxLength(const TV
 }
 
 static void getVariableInfo(ShShaderInfo varType,
                             const ShHandle handle,
                             int index,
                             int* length,
                             int* size,
                             ShDataType* type,
-                            char* name)
+                            char* name,
+                            char* mappedName)
 {
     if (!handle || !size || !type || !name)
         return;
     ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
            (varType == SH_ACTIVE_UNIFORMS));
 
     TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
     TCompiler* compiler = base->getAsCompiler();
@@ -54,16 +55,18 @@ static void getVariableInfo(ShShaderInfo
     if (index < 0 || index >= static_cast<int>(varList.size()))
         return;
 
     const TVariableInfo& varInfo = varList[index];
     if (length) *length = varInfo.name.size();
     *size = varInfo.size;
     *type = varInfo.type;
     strcpy(name, varInfo.name.c_str());
+    if (mappedName)
+        strcpy(mappedName, varInfo.mappedName.c_str());
 }
 
 //
 // Driver must call this first, once, before doing any other
 // compiler operations.
 //
 int ShInitialize()
 {
@@ -189,17 +192,19 @@ void ShGetInfo(const ShHandle handle, Sh
         *params = getVariableMaxLength(compiler->getUniforms());
         break;
     case SH_ACTIVE_ATTRIBUTES:
         *params = compiler->getAttribs().size();
         break;
     case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
         *params = getVariableMaxLength(compiler->getAttribs());
         break;
-
+    case SH_MAPPED_NAME_MAX_LENGTH:
+        *params = compiler->getMappedNameMaxLength();
+        break;
     default: UNREACHABLE();
     }
 }
 
 //
 // Return any compiler log of messages for the application.
 //
 void ShGetInfoLog(const ShHandle handle, char* infoLog)
@@ -231,24 +236,26 @@ void ShGetObjectCode(const ShHandle hand
     strcpy(objCode, infoSink.obj.c_str());
 }
 
 void ShGetActiveAttrib(const ShHandle handle,
                        int index,
                        int* length,
                        int* size,
                        ShDataType* type,
-                       char* name)
+                       char* name,
+                       char* mappedName)
 {
     getVariableInfo(SH_ACTIVE_ATTRIBUTES,
-                    handle, index, length, size, type, name);
+                    handle, index, length, size, type, name, mappedName);
 }
 
 void ShGetActiveUniform(const ShHandle handle,
                         int index,
                         int* length,
                         int* size,
                         ShDataType* type,
-                        char* name)
+                        char* name,
+                        char* mappedName)
 {
     getVariableInfo(SH_ACTIVE_UNIFORMS,
-                    handle, index, length, size, type, name);
+                    handle, index, length, size, type, name, mappedName);
 }
--- a/gfx/angle/src/compiler/ValidateLimitations.cpp
+++ b/gfx/angle/src/compiler/ValidateLimitations.cpp
@@ -12,16 +12,27 @@ namespace {
 bool IsLoopIndex(const TIntermSymbol* symbol, const TLoopStack& stack) {
     for (TLoopStack::const_iterator i = stack.begin(); i != stack.end(); ++i) {
         if (i->index.id == symbol->getId())
             return true;
     }
     return false;
 }
 
+void MarkLoopForUnroll(const TIntermSymbol* symbol, TLoopStack& stack) {
+    for (TLoopStack::iterator i = stack.begin(); i != stack.end(); ++i) {
+        if (i->index.id == symbol->getId()) {
+            ASSERT(i->loop != NULL);
+            i->loop->setUnrollFlag(true);
+            return;
+        }
+    }
+    UNREACHABLE();
+}
+
 // Traverses a node to check if it represents a constant index expression.
 // Definition:
 // constant-index-expressions are a superset of constant-expressions.
 // Constant-index-expressions can include loop indices as defined in
 // GLSL ES 1.0 spec, Appendix A, section 4.
 // The following are constant-index-expressions:
 // - Constant expressions
 // - Loop indices as defined in section 4
@@ -49,16 +60,58 @@ public:
     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,
+// mark the loop for unroll.
+class ValidateLoopIndexExpr : public TIntermTraverser {
+public:
+    ValidateLoopIndexExpr(TLoopStack& stack)
+        : mUsesFloatLoopIndex(false),
+          mUsesIntLoopIndex(false),
+          mLoopStack(stack) {}
+
+    bool usesFloatLoopIndex() const { return mUsesFloatLoopIndex; }
+    bool usesIntLoopIndex() const { return mUsesIntLoopIndex; }
+
+    virtual void visitSymbol(TIntermSymbol* symbol) {
+        if (IsLoopIndex(symbol, mLoopStack)) {
+            switch (symbol->getBasicType()) {
+              case EbtFloat:
+                mUsesFloatLoopIndex = true;
+                break;
+              case EbtInt:
+                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)
 {
@@ -75,17 +128,38 @@ void ValidateLimitations::visitConstantU
 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:
+        validateIndexing(node);
+        break;
       case EOpIndexIndirect:
+#if defined(__APPLE__)
+        // Loop unrolling is a work-around for a Mac Cg compiler bug where it
+        // crashes when a sampler array's index is also the loop index.
+        // Once Apple fixes this bug, we should remove the code in this CL.
+        // See http://codereview.appspot.com/4331048/.
+        if ((node->getLeft() != NULL) && (node->getRight() != NULL) &&
+            (node->getLeft()->getAsSymbolNode())) {
+            TIntermSymbol* symbol = node->getLeft()->getAsSymbolNode();
+            if (IsSampler(symbol->getBasicType()) && symbol->isArray()) {
+                ValidateLoopIndexExpr validate(mLoopStack);
+                node->getRight()->traverse(&validate);
+                if (validate.usesFloatLoopIndex()) {
+                    error(node->getLine(),
+                          "sampler array index is float loop index",
+                          "for");
+                }
+            }
+        }
+#endif
         validateIndexing(node);
         break;
       default: break;
     }
     return true;
 }
 
 bool ValidateLimitations::visitUnary(Visit, TIntermUnary* node)
@@ -115,16 +189,17 @@ bool ValidateLimitations::visitAggregate
 
 bool ValidateLimitations::visitLoop(Visit, TIntermLoop* node)
 {
     if (!validateLoopType(node))
         return false;
 
     TLoopInfo info;
     memset(&info, 0, sizeof(TLoopInfo));
+    info.loop = node;
     if (!validateForLoopHeader(node, &info))
         return false;
 
     TIntermNode* body = node->getBody();
     if (body != NULL) {
         mLoopStack.push_back(info);
         body->traverse(this);
         mLoopStack.pop_back();
--- a/gfx/angle/src/compiler/ValidateLimitations.h
+++ b/gfx/angle/src/compiler/ValidateLimitations.h
@@ -8,16 +8,17 @@
 #include "compiler/intermediate.h"
 
 class TInfoSinkBase;
 
 struct TLoopInfo {
     struct TIndex {
         int id;  // symbol id.
     } index;
+    TIntermLoop* loop;
 };
 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);
--- a/gfx/angle/src/compiler/VariableInfo.cpp
+++ b/gfx/angle/src/compiler/VariableInfo.cpp
@@ -65,70 +65,78 @@ static ShDataType getVariableDataType(co
       case EbtSamplerCube: return SH_SAMPLER_CUBE;
       default: UNREACHABLE();
     }
     return SH_NONE;
 }
 
 static void getBuiltInVariableInfo(const TType& type,
                                    const TString& name,
+                                   const TString& mappedName,
                                    TVariableInfoList& infoList);
 static void getUserDefinedVariableInfo(const TType& type,
                                        const TString& name,
+                                       const TString& mappedName,
                                        TVariableInfoList& infoList);
 
 // Returns info for an attribute or uniform.
 static void getVariableInfo(const TType& type,
                             const TString& name,
+                            const TString& mappedName,
                             TVariableInfoList& infoList)
 {
     if (type.getBasicType() == EbtStruct) {
         if (type.isArray()) {
             for (int i = 0; i < type.getArraySize(); ++i) {
                 TString lname = name + arrayBrackets(i);
-                getUserDefinedVariableInfo(type, lname, infoList);
+                TString lmappedName = mappedName + arrayBrackets(i);
+                getUserDefinedVariableInfo(type, lname, lmappedName, infoList);
             }
         } else {
-            getUserDefinedVariableInfo(type, name, infoList);
+            getUserDefinedVariableInfo(type, name, mappedName, infoList);
         }
     } else {
-        getBuiltInVariableInfo(type, name, infoList);
+        getBuiltInVariableInfo(type, name, mappedName, infoList);
     }
 }
 
 void getBuiltInVariableInfo(const TType& type,
                             const TString& name,
+                            const TString& mappedName,
                             TVariableInfoList& infoList)
 {
     ASSERT(type.getBasicType() != EbtStruct);
 
     TVariableInfo varInfo;
     if (type.isArray()) {
         varInfo.name = (name + "[0]").c_str();
+        varInfo.mappedName = (mappedName + "[0]").c_str();
         varInfo.size = type.getArraySize();
     } else {
         varInfo.name = name.c_str();
+        varInfo.mappedName = mappedName.c_str();
         varInfo.size = 1;
     }
     varInfo.type = getVariableDataType(type);
     infoList.push_back(varInfo);
 }
 
 void getUserDefinedVariableInfo(const TType& type,
                                 const TString& name,
+                                const TString& mappedName,
                                 TVariableInfoList& infoList)
 {
     ASSERT(type.getBasicType() == EbtStruct);
 
-    TString lname = name + ".";
     const TTypeList* structure = type.getStruct();
     for (size_t i = 0; i < structure->size(); ++i) {
         const TType* fieldType = (*structure)[i].type;
         getVariableInfo(*fieldType,
-                        lname + fieldType->getFieldName(),
+                        name + "." + fieldType->getFieldName(),
+                        mappedName + "." + fieldType->getFieldName(),
                         infoList);
     }
 }
 
 CollectAttribsUniforms::CollectAttribsUniforms(TVariableInfoList& attribs,
                                                TVariableInfoList& uniforms)
     : mAttribs(attribs),
       mUniforms(uniforms)
@@ -181,17 +189,19 @@ bool CollectAttribsUniforms::visitAggreg
             {
                 const TIntermSymbol* variable = (*i)->getAsSymbolNode();
                 // The only case in which the sequence will not contain a
                 // TIntermSymbol node is initialization. It will contain a
                 // TInterBinary node in that case. Since attributes and unifroms
                 // cannot be initialized in a shader, we must have only
                 // TIntermSymbol nodes in the sequence.
                 ASSERT(variable != NULL);
-                getVariableInfo(variable->getType(), variable->getSymbol(),
+                getVariableInfo(variable->getType(),
+                                variable->getOriginalSymbol(),
+                                variable->getSymbol(),
                                 infoList);
             }
         }
         break;
     }
     default: break;
     }
 
--- a/gfx/angle/src/compiler/VariableInfo.h
+++ b/gfx/angle/src/compiler/VariableInfo.h
@@ -1,21 +1,25 @@
 //
-// 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 COMPILER_VARIABLE_INFO_H_
+#define COMPILER_VARIABLE_INFO_H_
+
 #include "GLSLANG/ShaderLang.h"
 #include "compiler/intermediate.h"
 
 // Provides information about a variable.
 // It is currently being used to store info about active attribs and uniforms.
 struct TVariableInfo {
     TPersistString name;
+    TPersistString mappedName;
     ShDataType type;
     int size;
 };
 typedef std::vector<TVariableInfo> TVariableInfoList;
 
 // Traverses intermediate tree to collect all attributes and uniforms.
 class CollectAttribsUniforms : public TIntermTraverser {
 public:
@@ -31,8 +35,9 @@ public:
     virtual bool visitLoop(Visit, TIntermLoop*);
     virtual bool visitBranch(Visit, TIntermBranch*);
 
 private:
     TVariableInfoList& mAttribs;
     TVariableInfoList& mUniforms;
 };
 
+#endif  // COMPILER_VARIABLE_INFO_H_
--- a/gfx/angle/src/compiler/glslang.y
+++ b/gfx/angle/src/compiler/glslang.y
@@ -1180,26 +1180,30 @@ init_declarator_list
         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 {
-        $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, context->intermediate.addSymbol(0, *$3.string, TType($1.type), $3.line), $3.line);
+        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();
 
         if (context->nonInitConstErrorCheck($3.line, *$3.string, $$.type))
             context->recover();
 
-        if (context->nonInitErrorCheck($3.line, *$3.string, $$.type))
+        TVariable* variable = 0;
+        if (context->nonInitErrorCheck($3.line, *$3.string, $$.type, variable))
             context->recover();
+        if (symbol && variable)
+            symbol->setId(variable->getUniqueId());
     }
     | init_declarator_list COMMA IDENTIFIER LEFT_BRACKET RIGHT_BRACKET {
         if (context->structQualifierErrorCheck($3.line, $1.type))
             context->recover();
 
         if (context->nonInitConstErrorCheck($3.line, *$3.string, $1.type))
             context->recover();
 
@@ -1225,22 +1229,22 @@ init_declarator_list
 
         if (context->arrayTypeErrorCheck($4.line, $1.type) || context->arrayQualifierErrorCheck($4.line, $1.type))
             context->recover();
         else {
             int size;
             if (context->arraySizeErrorCheck($4.line, $5, size))
                 context->recover();
             $1.type.setArray(true, size);
-            TVariable* variable;
+            TVariable* variable = 0;
             if (context->arrayErrorCheck($4.line, *$3.string, $1.type, variable))
                 context->recover();
             TType type = TType($1.type);
             type.setArraySize(size);
-            $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, context->intermediate.addSymbol(0, *$3.string, type, $3.line), $3.line);
+            $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, context->intermediate.addSymbol(variable ? variable->getUniqueId() : 0, *$3.string, type, $3.line), $3.line);
         }
     }
     | init_declarator_list COMMA IDENTIFIER EQUAL initializer {
         if (context->structQualifierErrorCheck($3.line, $1.type))
             context->recover();
 
         $$ = $1;
 
@@ -1261,56 +1265,64 @@ init_declarator_list
     ;
 
 single_declaration
     : fully_specified_type {
         $$.type = $1;
         $$.intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, "", TType($1), $1.line), $1.line);
     }
     | fully_specified_type IDENTIFIER {
-        $$.intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, *$2.string, TType($1), $2.line), $2.line);
+        TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, TType($1), $2.line);
+        $$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line);
         
         if (context->structQualifierErrorCheck($2.line, $$.type))
             context->recover();
 
         if (context->nonInitConstErrorCheck($2.line, *$2.string, $$.type))
             context->recover();
             
             $$.type = $1;
 
-        if (context->nonInitErrorCheck($2.line, *$2.string, $$.type))
+        TVariable* variable = 0;
+        if (context->nonInitErrorCheck($2.line, *$2.string, $$.type, variable))
             context->recover();
+        if (variable && symbol)
+            symbol->setId(variable->getUniqueId());
     }
     | fully_specified_type IDENTIFIER LEFT_BRACKET RIGHT_BRACKET {
-        $$.intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, *$2.string, TType($1), $2.line), $2.line);
+        TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, TType($1), $2.line);
+        $$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line);
         
         if (context->structQualifierErrorCheck($2.line, $1))
             context->recover();
 
         if (context->nonInitConstErrorCheck($2.line, *$2.string, $1))
             context->recover();
 
         $$.type = $1;
 
         if (context->arrayTypeErrorCheck($3.line, $1) || context->arrayQualifierErrorCheck($3.line, $1))
             context->recover();
         else {
             $1.setArray(true);
-            TVariable* variable;
+            TVariable* variable = 0;
             if (context->arrayErrorCheck($3.line, *$2.string, $1, variable))
                 context->recover();
+            if (variable && symbol)
+                symbol->setId(variable->getUniqueId());
         }
     }
     | fully_specified_type IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET {
         TType type = TType($1);
         int size;
         if (context->arraySizeErrorCheck($2.line, $4, size))
             context->recover();
         type.setArraySize(size);
-        $$.intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, *$2.string, type, $2.line), $2.line);
+        TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, type, $2.line);
+        $$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line);
         
         if (context->structQualifierErrorCheck($2.line, $1))
             context->recover();
 
         if (context->nonInitConstErrorCheck($2.line, *$2.string, $1))
             context->recover();
 
         $$.type = $1;
@@ -1318,19 +1330,21 @@ single_declaration
         if (context->arrayTypeErrorCheck($3.line, $1) || context->arrayQualifierErrorCheck($3.line, $1))
             context->recover();
         else {
             int size;
             if (context->arraySizeErrorCheck($3.line, $4, size))
                 context->recover();
 
             $1.setArray(true, size);
-            TVariable* variable;
+            TVariable* variable = 0;
             if (context->arrayErrorCheck($3.line, *$2.string, $1, variable))
                 context->recover();
+            if (variable && symbol)
+                symbol->setId(variable->getUniqueId());
         }
     }
     | fully_specified_type IDENTIFIER EQUAL initializer {
         if (context->structQualifierErrorCheck($2.line, $1))
             context->recover();
 
         $$.type = $1;
 
--- a/gfx/angle/src/compiler/glslang_tab.cpp
+++ b/gfx/angle/src/compiler/glslang_tab.cpp
@@ -320,17 +320,17 @@ typedef union YYSTYPE
             TQualifier qualifier;
             TFunction* function;
             TParameter param;
             TTypeLine typeLine;
             TTypeList* typeList;
         };
     } interm;
 }
-/* Line 187 of yacc.c.  */
+/* Line 193 of yacc.c.  */
 
 	YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
 #endif
 
 
@@ -410,17 +410,17 @@ typedef short int yytype_int16;
 # else
 #  define YYSIZE_T unsigned int
 # endif
 #endif
 
 #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
 
 #ifndef YY_
-# if YYENABLE_NLS
+# if defined YYENABLE_NLS && 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
@@ -733,27 +733,27 @@ static const yytype_uint16 yyrline[] =
      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,  1199,  1217,  1241,  1264,  1268,  1282,  1302,
-    1331,  1351,  1427,  1436,  1459,  1462,  1468,  1476,  1484,  1492,
-    1495,  1502,  1505,  1508,  1514,  1517,  1532,  1536,  1540,  1544,
-    1553,  1558,  1563,  1568,  1573,  1578,  1583,  1588,  1593,  1598,
-    1604,  1610,  1616,  1621,  1626,  1631,  1644,  1657,  1665,  1668,
-    1683,  1714,  1718,  1724,  1732,  1748,  1752,  1756,  1757,  1763,
-    1764,  1765,  1766,  1767,  1771,  1772,  1772,  1772,  1782,  1783,
-    1788,  1791,  1801,  1804,  1810,  1811,  1815,  1823,  1827,  1837,
-    1842,  1859,  1859,  1864,  1864,  1871,  1871,  1879,  1882,  1888,
-    1891,  1897,  1901,  1908,  1915,  1922,  1929,  1940,  1949,  1953,
-    1960,  1963,  1969,  1969
+    1170,  1177,  1187,  1203,  1221,  1245,  1268,  1272,  1290,  1313,
+    1345,  1365,  1441,  1450,  1473,  1476,  1482,  1490,  1498,  1506,
+    1509,  1516,  1519,  1522,  1528,  1531,  1546,  1550,  1554,  1558,
+    1567,  1572,  1577,  1582,  1587,  1592,  1597,  1602,  1607,  1612,
+    1618,  1624,  1630,  1635,  1640,  1645,  1658,  1671,  1679,  1682,
+    1697,  1728,  1732,  1738,  1746,  1762,  1766,  1770,  1771,  1777,
+    1778,  1779,  1780,  1781,  1785,  1786,  1786,  1786,  1796,  1797,
+    1802,  1805,  1815,  1818,  1824,  1825,  1829,  1837,  1841,  1851,
+    1856,  1873,  1873,  1878,  1878,  1885,  1885,  1893,  1896,  1902,
+    1905,  1911,  1915,  1922,  1929,  1936,  1943,  1954,  1963,  1967,
+    1974,  1977,  1983,  1983
 };
 #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[] =
 {
@@ -1356,17 +1356,17 @@ while (YYID (0))
 #endif
 
 
 /* YY_LOCATION_PRINT -- Print the location on the stream.
    This macro was not mandated originally: define only if we know
    we won't break user code: when these are the locations we know.  */
 
 #ifndef YY_LOCATION_PRINT
-# if YYLTYPE_IS_TRIVIAL
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
 #  define YY_LOCATION_PRINT(File, Loc)			\
      fprintf (File, "%d.%d-%d.%d",			\
 	      (Loc).first_line, (Loc).first_column,	\
 	      (Loc).last_line,  (Loc).last_column)
 # else
 #  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
 # endif
 #endif
@@ -3368,26 +3368,30 @@ yyreduce:
             }
         }
     ;}
     break;
 
   case 92:
 
     {
-        (yyval.interm).intermAggregate = context->intermediate.growAggregate((yyvsp[(1) - (3)].interm).intermNode, context->intermediate.addSymbol(0, *(yyvsp[(3) - (3)].lex).string, TType((yyvsp[(1) - (3)].interm).type), (yyvsp[(3) - (3)].lex).line), (yyvsp[(3) - (3)].lex).line);
+        TIntermSymbol* symbol = context->intermediate.addSymbol(0, *(yyvsp[(3) - (3)].lex).string, TType((yyvsp[(1) - (3)].interm).type), (yyvsp[(3) - (3)].lex).line);
+        (yyval.interm).intermAggregate = context->intermediate.growAggregate((yyvsp[(1) - (3)].interm).intermNode, symbol, (yyvsp[(3) - (3)].lex).line);
         
         if (context->structQualifierErrorCheck((yyvsp[(3) - (3)].lex).line, (yyval.interm).type))
             context->recover();
 
         if (context->nonInitConstErrorCheck((yyvsp[(3) - (3)].lex).line, *(yyvsp[(3) - (3)].lex).string, (yyval.interm).type))
             context->recover();
 
-        if (context->nonInitErrorCheck((yyvsp[(3) - (3)].lex).line, *(yyvsp[(3) - (3)].lex).string, (yyval.interm).type))
+        TVariable* variable = 0;
+        if (context->nonInitErrorCheck((yyvsp[(3) - (3)].lex).line, *(yyvsp[(3) - (3)].lex).string, (yyval.interm).type, variable))
             context->recover();
+        if (symbol && variable)
+            symbol->setId(variable->getUniqueId());
     ;}
     break;
 
   case 93:
 
     {
         if (context->structQualifierErrorCheck((yyvsp[(3) - (5)].lex).line, (yyvsp[(1) - (5)].interm).type))
             context->recover();
@@ -3421,22 +3425,22 @@ yyreduce:
 
         if (context->arrayTypeErrorCheck((yyvsp[(4) - (6)].lex).line, (yyvsp[(1) - (6)].interm).type) || context->arrayQualifierErrorCheck((yyvsp[(4) - (6)].lex).line, (yyvsp[(1) - (6)].interm).type))
             context->recover();
         else {
             int size;
             if (context->arraySizeErrorCheck((yyvsp[(4) - (6)].lex).line, (yyvsp[(5) - (6)].interm.intermTypedNode), size))
                 context->recover();
             (yyvsp[(1) - (6)].interm).type.setArray(true, size);
-            TVariable* variable;
+            TVariable* variable = 0;
             if (context->arrayErrorCheck((yyvsp[(4) - (6)].lex).line, *(yyvsp[(3) - (6)].lex).string, (yyvsp[(1) - (6)].interm).type, variable))
                 context->recover();
             TType type = TType((yyvsp[(1) - (6)].interm).type);
             type.setArraySize(size);
-            (yyval.interm).intermAggregate = context->intermediate.growAggregate((yyvsp[(1) - (6)].interm).intermNode, context->intermediate.addSymbol(0, *(yyvsp[(3) - (6)].lex).string, type, (yyvsp[(3) - (6)].lex).line), (yyvsp[(3) - (6)].lex).line);
+            (yyval.interm).intermAggregate = context->intermediate.growAggregate((yyvsp[(1) - (6)].interm).intermNode, context->intermediate.addSymbol(variable ? variable->getUniqueId() : 0, *(yyvsp[(3) - (6)].lex).string, type, (yyvsp[(3) - (6)].lex).line), (yyvsp[(3) - (6)].lex).line);
         }
     ;}
     break;
 
   case 95:
 
     {
         if (context->structQualifierErrorCheck((yyvsp[(3) - (5)].lex).line, (yyvsp[(1) - (5)].interm).type))
@@ -3466,64 +3470,72 @@ yyreduce:
         (yyval.interm).type = (yyvsp[(1) - (1)].interm.type);
         (yyval.interm).intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, "", TType((yyvsp[(1) - (1)].interm.type)), (yyvsp[(1) - (1)].interm.type).line), (yyvsp[(1) - (1)].interm.type).line);
     ;}
     break;
 
   case 97:
 
     {
-        (yyval.interm).intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, *(yyvsp[(2) - (2)].lex).string, TType((yyvsp[(1) - (2)].interm.type)), (yyvsp[(2) - (2)].lex).line), (yyvsp[(2) - (2)].lex).line);
+        TIntermSymbol* symbol = context->intermediate.addSymbol(0, *(yyvsp[(2) - (2)].lex).string, TType((yyvsp[(1) - (2)].interm.type)), (yyvsp[(2) - (2)].lex).line);
+        (yyval.interm).intermAggregate = context->intermediate.makeAggregate(symbol, (yyvsp[(2) - (2)].lex).line);
         
         if (context->structQualifierErrorCheck((yyvsp[(2) - (2)].lex).line, (yyval.interm).type))
             context->recover();
 
         if (context->nonInitConstErrorCheck((yyvsp[(2) - (2)].lex).line, *(yyvsp[(2) - (2)].lex).string, (yyval.interm).type))
             context->recover();
             
             (yyval.interm).type = (yyvsp[(1) - (2)].interm.type);
 
-        if (context->nonInitErrorCheck((yyvsp[(2) - (2)].lex).line, *(yyvsp[(2) - (2)].lex).string, (yyval.interm).type))
+        TVariable* variable = 0;
+        if (context->nonInitErrorCheck((yyvsp[(2) - (2)].lex).line, *(yyvsp[(2) - (2)].lex).string, (yyval.interm).type, variable))
             context->recover();
+        if (variable && symbol)
+            symbol->setId(variable->getUniqueId());
     ;}
     break;
 
   case 98:
 
     {
-        (yyval.interm).intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, *(yyvsp[(2) - (4)].lex).string, TType((yyvsp[(1) - (4)].interm.type)), (yyvsp[(2) - (4)].lex).line), (yyvsp[(2) - (4)].lex).line);
+        TIntermSymbol* symbol = context->intermediate.addSymbol(0, *(yyvsp[(2) - (4)].lex).string, TType((yyvsp[(1) - (4)].interm.type)), (yyvsp[(2) - (4)].lex).line);
+        (yyval.interm).intermAggregate = context->intermediate.makeAggregate(symbol, (yyvsp[(2) - (4)].lex).line);
         
         if (context->structQualifierErrorCheck((yyvsp[(2) - (4)].lex).line, (yyvsp[(1) - (4)].interm.type)))
             context->recover();
 
         if (context->nonInitConstErrorCheck((yyvsp[(2) - (4)].lex).line, *(yyvsp[(2) - (4)].lex).string, (yyvsp[(1) - (4)].interm.type)))
             context->recover();
 
         (yyval.interm).type = (yyvsp[(1) - (4)].interm.type);
 
         if (context->arrayTypeErrorCheck((yyvsp[(3) - (4)].lex).line, (yyvsp[(1) - (4)].interm.type)) || context->arrayQualifierErrorCheck((yyvsp[(3) - (4)].lex).line, (yyvsp[(1) - (4)].interm.type)))
             context->recover();
         else {
             (yyvsp[(1) - (4)].interm.type).setArray(true);
-            TVariable* variable;
+            TVariable* variable = 0;
             if (context->arrayErrorCheck((yyvsp[(3) - (4)].lex).line, *(yyvsp[(2) - (4)].lex).string, (yyvsp[(1) - (4)].interm.type), variable))
                 context->recover();
+            if (variable && symbol)
+                symbol->setId(variable->getUniqueId());
         }
     ;}
     break;
 
   case 99:
 
     {
         TType type = TType((yyvsp[(1) - (5)].interm.type));
         int size;
         if (context->arraySizeErrorCheck((yyvsp[(2) - (5)].lex).line, (yyvsp[(4) - (5)].interm.intermTypedNode), size))
             context->recover();
         type.setArraySize(size);
-        (yyval.interm).intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, *(yyvsp[(2) - (5)].lex).string, type, (yyvsp[(2) - (5)].lex).line), (yyvsp[(2) - (5)].lex).line);
+        TIntermSymbol* symbol = context->intermediate.addSymbol(0, *(yyvsp[(2) - (5)].lex).string, type, (yyvsp[(2) - (5)].lex).line);
+        (yyval.interm).intermAggregate = context->intermediate.makeAggregate(symbol, (yyvsp[(2) - (5)].lex).line);
         
         if (context->structQualifierErrorCheck((yyvsp[(2) - (5)].lex).line, (yyvsp[(1) - (5)].interm.type)))
             context->recover();
 
         if (context->nonInitConstErrorCheck((yyvsp[(2) - (5)].lex).line, *(yyvsp[(2) - (5)].lex).string, (yyvsp[(1) - (5)].interm.type)))
             context->recover();
 
         (yyval.interm).type = (yyvsp[(1) - (5)].interm.type);
@@ -3531,19 +3543,21 @@ yyreduce:
         if (context->arrayTypeErrorCheck((yyvsp[(3) - (5)].lex).line, (yyvsp[(1) - (5)].interm.type)) || context->arrayQualifierErrorCheck((yyvsp[(3) - (5)].lex).line, (yyvsp[(1) - (5)].interm.type)))
             context->recover();
         else {
             int size;
             if (context->arraySizeErrorCheck((yyvsp[(3) - (5)].lex).line, (yyvsp[(4) - (5)].interm.intermTypedNode), size))
                 context->recover();
 
             (yyvsp[(1) - (5)].interm.type).setArray(true, size);
-            TVariable* variable;
+            TVariable* variable = 0;
             if (context->arrayErrorCheck((yyvsp[(3) - (5)].lex).line, *(yyvsp[(2) - (5)].lex).string, (yyvsp[(1) - (5)].interm.type), variable))
                 context->recover();
+            if (variable && symbol)
+                symbol->setId(variable->getUniqueId());
         }
     ;}
     break;
 
   case 100:
 
     {
         if (context->structQualifierErrorCheck((yyvsp[(2) - (4)].lex).line, (yyvsp[(1) - (4)].interm.type)))
--- a/gfx/angle/src/compiler/glslang_tab.h
+++ b/gfx/angle/src/compiler/glslang_tab.h
@@ -257,17 +257,17 @@ typedef union YYSTYPE
             TQualifier qualifier;
             TFunction* function;
             TParameter param;
             TTypeLine typeLine;
             TTypeList* typeList;
         };
     } interm;
 }
-/* Line 1489 of yacc.c.  */
+/* Line 1529 of yacc.c.  */
 
 	YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
 #endif
 
 
--- a/gfx/angle/src/compiler/intermediate.h
+++ b/gfx/angle/src/compiler/intermediate.h
@@ -274,33 +274,39 @@ class TIntermLoop : public TIntermNode {
 public:
     TIntermLoop(TLoopType aType,
                 TIntermNode *aInit, TIntermTyped* aCond, TIntermTyped* aExpr,
                 TIntermNode* aBody) :
             type(aType),
             init(aInit),
             cond(aCond),
             expr(aExpr),
-            body(aBody) { }
+            body(aBody),
+            unrollFlag(false) { }
 
     virtual TIntermLoop* getAsLoopNode() { return this; }
     virtual void traverse(TIntermTraverser*);
 
     TLoopType getType() const { return type; }
     TIntermNode* getInit() { return init; }
     TIntermTyped* getCondition() { return cond; }
     TIntermTyped* getExpression() { return expr; }
     TIntermNode* getBody() { return body; }
 
+    void setUnrollFlag(bool flag) { unrollFlag = flag; }
+    bool getUnrollFlag() { return unrollFlag; }
+
 protected:
     TLoopType type;
     TIntermNode* init;  // for-loop initialization
     TIntermTyped* cond; // loop exit condition
     TIntermTyped* expr; // for-loop expression
     TIntermNode* body;  // loop body
+
+    bool unrollFlag; // Whether the loop should be unrolled or not.
 };
 
 //
 // Handle break, continue, return, and kill.
 //
 class TIntermBranch : public TIntermNode {
 public:
     TIntermBranch(TOperator op, TIntermTyped* e) :
@@ -321,27 +327,33 @@ protected:
 // Nodes that correspond to symbols or constants in the source code.
 //
 class TIntermSymbol : public TIntermTyped {
 public:
     // if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym. If sym comes from
     // per process globalpoolallocator, then it causes increased memory usage per compile
     // it is essential to use "symbol = sym" to assign to symbol
     TIntermSymbol(int i, const TString& sym, const TType& t) : 
-            TIntermTyped(t), id(i)  { symbol = sym;} 
+            TIntermTyped(t), id(i)  { symbol = sym; originalSymbol = sym; } 
 
     int getId() const { return id; }
     const TString& getSymbol() const { return symbol; }
 
+    void setId(int newId) { id = newId; }
+    void setSymbol(const TString& sym) { symbol = sym; }
+
+    const TString& getOriginalSymbol() const { return originalSymbol; }
+
     virtual void traverse(TIntermTraverser*);
     virtual TIntermSymbol* getAsSymbolNode() { return this; }
 
 protected:
     int id;
     TString symbol;
+    TString originalSymbol;
 };
 
 class TIntermConstantUnion : public TIntermTyped {
 public:
     TIntermConstantUnion(ConstantUnion *unionPointer, const TType& t) : TIntermTyped(t), unionArrayPointer(unionPointer) { }
 
     ConstantUnion* getUnionArrayPointer() const { return unionArrayPointer; }
     void setUnionArrayPointer(ConstantUnion *c) { unionArrayPointer = c; }
--- a/gfx/angle/src/compiler/preprocessor/cpp.c
+++ b/gfx/angle/src/compiler/preprocessor/cpp.c
@@ -463,16 +463,27 @@ static int eval(int token, int prec, int
             if (binop[i].token == token)
                 break;
         }
         if (i < 0 || binop[i].prec <= prec)
             break;
         val = *res;
         token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
         token = eval(token, binop[i].prec, res, err, yylvalpp);
+        
+        if (binop[i].op == op_div || binop[i].op == op_mod)
+        {
+            if (*res == 0)
+            {
+                CPPErrorToInfoLog("preprocessor divide or modulo by zero");
+                *err = 1;
+                return token;
+            }
+        }
+
         *res = binop[i].op(val, *res);
     }
     return token;
 error:
     CPPErrorToInfoLog("incorrect preprocessor directive");
     *err = 1;
     *res = 0;
     return token;
--- a/gfx/angle/src/compiler/preprocessor/scanner.c
+++ b/gfx/angle/src/compiler/preprocessor/scanner.c
@@ -368,17 +368,17 @@ static int byte_scan(InputSrc *in, yysty
             }
             // Fall through...
         case '1': case '2': case '3': case '4':
         case '5': case '6': case '7': case '8': case '9':
             do {
                 APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
                 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
             } while (ch >= '0' && ch <= '9');
-            if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E') {
+            if (ch == '.' || ch == 'e' || ch == 'E') {
                 return lFloatConst(ch, len, yylvalpp);
             } else {
                 assert(len <= MAX_SYMBOL_NAME_LEN);
                 yylvalpp->symbol_name[len] = '\0';
                 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
                 ival = 0;
                 for (ii = 0; ii < len; ii++) {
                     ch = yylvalpp->symbol_name[ii] - '0';
@@ -553,36 +553,31 @@ static int byte_scan(InputSrc *in, yysty
             if (ch == '/') {
                 do {
                     ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
                 } while (ch != '\n' && ch != EOF);
                 if (ch == EOF)
                     return -1;
                 return '\n';
             } else if (ch == '*') {
-                int nlcount = 0;
                 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
                 do {
                     while (ch != '*') {
-                        if (ch == '\n') nlcount++;
                         if (ch == EOF) {
                             CPPErrorToInfoLog("EOF IN COMMENT");
                             return -1;
                         }
                         ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
                     }
                     ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
                     if (ch == EOF) {
                         CPPErrorToInfoLog("EOF IN COMMENT");
                         return -1;
                     }
                 } while (ch != '/');
-                if (nlcount) {
-                    return '\n';
-                }
                 // Go try it again...
             } else if (ch == '=') {
                 return CPP_DIV_ASSIGN;
             } else {
                 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
                 return '/';
             }
             break;
--- a/gfx/angle/src/compiler/preprocessor/scanner.h
+++ b/gfx/angle/src/compiler/preprocessor/scanner.h
@@ -44,17 +44,17 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILI
 //
 // scanner.h
 //
 
 #if !defined(__SCANNER_H)
 #define __SCANNER_H 1
 
 // These lengths do not include the NULL terminator.
-#define MAX_SYMBOL_NAME_LEN 127
+#define MAX_SYMBOL_NAME_LEN 256
 #define MAX_STRING_LEN 511
 
 #include "compiler/preprocessor/parser.h"
 
 // Not really atom table stuff but needed first...
 
 typedef struct SourceLoc_Rec {
     unsigned short file, line;
--- a/gfx/angle/src/libEGL/Config.cpp
+++ b/gfx/angle/src/libEGL/Config.cpp
@@ -59,16 +59,18 @@ void Config::setDefaults()
     mTransparentType = EGL_NONE;
     mTransparentRedValue = EGL_DONT_CARE;
     mTransparentGreenValue = EGL_DONT_CARE;
     mTransparentBlueValue = EGL_DONT_CARE;
 }
 
 void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample, EGLint texWidth, EGLint texHeight)
 {
+    mBindToTextureRGB = EGL_FALSE;
+    mBindToTextureRGBA = EGL_FALSE;
     switch (renderTargetFormat)
     {
       case D3DFMT_A1R5G5B5:
         mBufferSize = 16;
         mRedSize = 5;
         mGreenSize = 5;
         mBlueSize = 5;
         mAlphaSize = 1;
@@ -81,46 +83,50 @@ void Config::set(D3DDISPLAYMODE displayM
         mAlphaSize = 2;
         break;
       case D3DFMT_A8R8G8B8:
         mBufferSize = 32;
         mRedSize = 8;
         mGreenSize = 8;
         mBlueSize = 8;
         mAlphaSize = 8;
+        mBindToTextureRGBA = true;
         break;
       case D3DFMT_R5G6B5:
         mBufferSize = 16;
         mRedSize = 5;
         mGreenSize = 6;
         mBlueSize = 5;
         mAlphaSize = 0;
         break;
       case D3DFMT_X8R8G8B8:
         mBufferSize = 32;
         mRedSize = 8;
         mGreenSize = 8;
         mBlueSize = 8;
         mAlphaSize = 0;
+        mBindToTextureRGB = true;
         break;
       default:
         UNREACHABLE();   // Other formats should not be valid
     }
 
     mLuminanceSize = 0;
     mAlphaMaskSize = 0;
-    mBindToTextureRGB = EGL_FALSE;
-    mBindToTextureRGBA = EGL_FALSE;
     mColorBufferType = EGL_RGB_BUFFER;
     mConfigCaveat = (displayMode.Format == renderTargetFormat) ? EGL_NONE : EGL_SLOW_CONFIG;
     mConfigID = 0;
     mConformant = EGL_OPENGL_ES2_BIT;
 
     switch (depthStencilFormat)
     {
+      case D3DFMT_UNKNOWN:
+        mDepthSize = 0;
+        mStencilSize = 0;
+        break;
 //    case D3DFMT_D16_LOCKABLE:
 //      mDepthSize = 16;
 //      mStencilSize = 0;
 //      break;
       case D3DFMT_D32:
         mDepthSize = 32;
         mStencilSize = 0;
         break;
--- a/gfx/angle/src/libEGL/Display.cpp
+++ b/gfx/angle/src/libEGL/Display.cpp
@@ -1,39 +1,41 @@
 //
-// 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.
 //
 
 // Display.cpp: Implements the egl::Display class, representing the abstract
 // display on which graphics are drawn. Implements EGLDisplay.
 // [EGL 1.4] section 2.1.2 page 3.
 
 #include "libEGL/Display.h"
 
 #include <algorithm>
 #include <vector>
 
 #include "common/debug.h"
+#include "libGLESv2/mathutil.h"
 
 #include "libEGL/main.h"
 
 #define REF_RAST 0        // Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros
 #define ENABLE_D3D9EX 1   // Enables use of the IDirect3D9Ex interface, when available
 
 namespace egl
 {
 Display::Display(HDC deviceContext) : mDc(deviceContext)
 {
     mD3d9Module = NULL;
     
     mD3d9 = NULL;
-    mD3d9ex = NULL;
+    mD3d9Ex = NULL;
     mDevice = NULL;
+    mDeviceEx = NULL;
     mDeviceWindow = NULL;
 
     mAdapter = D3DADAPTER_DEFAULT;
 
     #if REF_RAST == 1 || defined(FORCE_REF_RAST)
         mDeviceType = D3DDEVTYPE_REF;
     #else
         mDeviceType = D3DDEVTYPE_HAL;
@@ -63,20 +65,20 @@ bool Display::initialize()
     }
 
     typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex**);
     Direct3DCreate9ExFunc Direct3DCreate9ExPtr = reinterpret_cast<Direct3DCreate9ExFunc>(GetProcAddress(mD3d9Module, "Direct3DCreate9Ex"));
 
     // Use Direct3D9Ex if available. Among other things, this version is less
     // inclined to report a lost context, for example when the user switches
     // desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are available.
-    if (ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9ex)))
+    if (ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex)))
     {
-        ASSERT(mD3d9ex);
-        mD3d9ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9));
+        ASSERT(mD3d9Ex);
+        mD3d9Ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9));
         ASSERT(mD3d9);
     }
     else
     {
         mD3d9 = Direct3DCreate9(D3D_SDK_VERSION);
     }
 
     if (mD3d9)
@@ -138,16 +140,17 @@ bool Display::initialize()
             D3DFMT_A8R8G8B8,
             D3DFMT_R5G6B5,
         //  D3DFMT_X1R5G5B5,      // Has no compatible OpenGL ES renderbuffer format
             D3DFMT_X8R8G8B8
         };
 
         const D3DFORMAT depthStencilFormats[] =
         {
+            D3DFMT_UNKNOWN,
         //  D3DFMT_D16_LOCKABLE,
             D3DFMT_D32,
         //  D3DFMT_D15S1,
             D3DFMT_D24S8,
             D3DFMT_D24X8,
         //  D3DFMT_D24X4S4,
             D3DFMT_D16,
         //  D3DFMT_D32F_LOCKABLE,
@@ -165,21 +168,29 @@ bool Display::initialize()
 
             HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, renderTargetFormat);
 
             if (SUCCEEDED(result))
             {
                 for (int depthStencilIndex = 0; depthStencilIndex < sizeof(depthStencilFormats) / sizeof(D3DFORMAT); depthStencilIndex++)
                 {
                     D3DFORMAT depthStencilFormat = depthStencilFormats[depthStencilIndex];
-                    HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFormat);
+                    HRESULT result = D3D_OK;
+                    
+                    if(depthStencilFormat != D3DFMT_UNKNOWN)
+                    {
+                        result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFormat);
+                    }
 
                     if (SUCCEEDED(result))
                     {
-                        HRESULT result = mD3d9->CheckDepthStencilMatch(mAdapter, mDeviceType, currentDisplayMode.Format, renderTargetFormat, depthStencilFormat);
+                        if(depthStencilFormat != D3DFMT_UNKNOWN)
+                        {
+                            result = mD3d9->CheckDepthStencilMatch(mAdapter, mDeviceType, currentDisplayMode.Format, renderTargetFormat, depthStencilFormat);
+                        }
 
                         if (SUCCEEDED(result))
                         {
                             // FIXME: enumerate multi-sampling
 
                             configSet.add(currentDisplayMode, mMinSwapInterval, mMaxSwapInterval, renderTargetFormat, depthStencilFormat, 0,
                                           mDeviceCaps.MaxTextureWidth, mDeviceCaps.MaxTextureHeight);
                         }
@@ -202,16 +213,18 @@ bool Display::initialize()
 
     if (!isInitialized())
     {
         terminate();
 
         return false;
     }
 
+    initExtensionString();
+
     static const TCHAR windowName[] = TEXT("AngleHiddenWindow");
     static const TCHAR className[] = TEXT("STATIC");
 
     mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
 
     return true;
 }
 
@@ -225,41 +238,47 @@ void Display::terminate()
     while (!mContextSet.empty())
     {
         destroyContext(*mContextSet.begin());
     }
 
     if (mDevice)
     {
         // If the device is lost, reset it first to prevent leaving the driver in an unstable state
-        if (FAILED(mDevice->TestCooperativeLevel()))
+        if (isDeviceLost())
         {
             resetDevice();
         }
 
         mDevice->Release();
         mDevice = NULL;
     }
 
+    if (mDeviceEx)
+    {
+        mDeviceEx->Release();
+        mDeviceEx = NULL;
+    }
+
     if (mD3d9)
     {
         mD3d9->Release();
         mD3d9 = NULL;
     }
 
     if (mDeviceWindow)
     {
         DestroyWindow(mDeviceWindow);
         mDeviceWindow = NULL;
     }
     
-    if (mD3d9ex)
+    if (mD3d9Ex)
     {
-        mD3d9ex->Release();
-        mD3d9ex = NULL;
+        mD3d9Ex->Release();
+        mD3d9Ex = NULL;
     }
 
     if (mD3d9Module)
     {
         mD3d9Module = NULL;
     }
 }
 
@@ -351,16 +370,22 @@ bool Display::createDevice()
 
         if (FAILED(result))
         {
             ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_NOTAVAILABLE || result == D3DERR_DEVICELOST);
             return error(EGL_BAD_ALLOC, false);
         }
     }
 
+    if (mD3d9Ex)
+    {
+        result = mDevice->QueryInterface(IID_IDirect3DDevice9Ex, (void**) &mDeviceEx);
+        ASSERT(SUCCEEDED(result));
+    }
+
     // Permanent non-default states
     mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
 
     mSceneStarted = false;
 
     return true;
 }
 
@@ -382,46 +407,184 @@ bool Display::resetDevice()
         return error(EGL_BAD_ALLOC, false);
     }
 
     ASSERT(SUCCEEDED(result));
 
     return true;
 }
 
-Surface *Display::createWindowSurface(HWND window, EGLConfig config)
+EGLSurface Display::createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList)
 {
     const Config *configuration = mConfigSet.get(config);
 
+    if (attribList)
+    {
+        while (*attribList != EGL_NONE)
+        {
+            switch (attribList[0])
+            {
+              case EGL_RENDER_BUFFER:
+                switch (attribList[1])
+                {
+                  case EGL_BACK_BUFFER:
+                    break;
+                  case EGL_SINGLE_BUFFER:
+                    return error(EGL_BAD_MATCH, EGL_NO_SURFACE);   // Rendering directly to front buffer not supported
+                  default:
+                    return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+                }
+                break;
+              case EGL_VG_COLORSPACE:
+                return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+              case EGL_VG_ALPHA_FORMAT:
+                return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+              default:
+                return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+            }
+
+            attribList += 2;
+        }
+    }
+
+    if (hasExistingWindowSurface(window))
+    {
+        return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+    }
+
     Surface *surface = new Surface(this, configuration, window);
+
+    if (!surface->initialize())
+    {
+        delete surface;
+        return EGL_NO_SURFACE;
+    }
+
     mSurfaceSet.insert(surface);
 
-    return surface;
+    return success(surface);
 }
 
-Surface *Display::createOffscreenSurface(int width, int height, EGLConfig config)
+EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList)
 {
+    EGLint width = 0, height = 0;
+    EGLenum textureFormat = EGL_NO_TEXTURE;
+    EGLenum textureTarget = EGL_NO_TEXTURE;
     const Config *configuration = mConfigSet.get(config);
 
-    Surface *surface = new Surface(this, configuration, width, height);
+    if (attribList)
+    {
+        while (*attribList != EGL_NONE)
+        {
+            switch (attribList[0])
+            {
+              case EGL_WIDTH:
+                width = attribList[1];
+                break;
+              case EGL_HEIGHT:
+                height = attribList[1];
+                break;
+              case EGL_LARGEST_PBUFFER:
+                if (attribList[1] != EGL_FALSE)
+                  UNIMPLEMENTED(); // FIXME
+                break;
+              case EGL_TEXTURE_FORMAT:
+                switch (attribList[1])
+                {
+                  case EGL_NO_TEXTURE:
+                  case EGL_TEXTURE_RGB:
+                  case EGL_TEXTURE_RGBA:
+                    textureFormat = attribList[1];
+                    break;
+                  default:
+                    return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+                }
+                break;
+              case EGL_TEXTURE_TARGET:
+                switch (attribList[1])
+                {
+                  case EGL_NO_TEXTURE:
+                  case EGL_TEXTURE_2D:
+                    textureTarget = attribList[1];
+                    break;
+                  default:
+                    return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+                }
+                break;
+              case EGL_MIPMAP_TEXTURE:
+                if (attribList[1] != EGL_FALSE)
+                  return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+                break;
+              case EGL_VG_COLORSPACE:
+                return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+              case EGL_VG_ALPHA_FORMAT:
+                return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+              default:
+                return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+            }
+
+            attribList += 2;
+        }
+    }
+
+    if (width < 0 || height < 0)
+    {
+        return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
+    }
+
+    if (width == 0 || height == 0)
+    {
+        return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+    }
+
+    if (textureFormat != EGL_NO_TEXTURE && !getNonPow2TextureSupport() && (!gl::isPow2(width) || !gl::isPow2(height)))
+    {
+        return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+    }
+
+    if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) ||
+        (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE))
+    {
+        return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+    }
+
+    if (!(configuration->mSurfaceType & EGL_PBUFFER_BIT))
+    {
+        return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+    }
+
+    if ((textureFormat == EGL_TEXTURE_RGB && configuration->mBindToTextureRGB != EGL_TRUE) ||
+        (textureFormat == EGL_TEXTURE_RGBA && configuration->mBindToTextureRGBA != EGL_TRUE))
+    {
+        return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+    }
+
+    Surface *surface = new Surface(this, configuration, shareHandle, width, height, textureFormat, textureTarget);
+
+    if (!surface->initialize())
+    {
+        delete surface;
+        return EGL_NO_SURFACE;
+    }
+
     mSurfaceSet.insert(surface);
 
-    return surface;
+    return success(surface);
 }
 
 EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *shareContext)
 {
     if (!mDevice)
     {
         if (!createDevice())
         {
             return NULL;
         }
     }
-    else if (FAILED(mDevice->TestCooperativeLevel()))   // Lost device
+    else if (isDeviceLost())   // Lost device
     {
         if (!resetDevice())
         {
             return NULL;
         }
 
         // Restore any surfaces that may have been lost
         for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
@@ -435,52 +598,59 @@ EGLContext Display::createContext(EGLCon
     gl::Context *context = glCreateContext(config, shareContext);
     mContextSet.insert(context);
 
     return context;
 }
 
 void Display::destroySurface(egl::Surface *surface)
 {
-    delete surface;
-    mSurfaceSet.erase(surface);
+    if (surface == egl::getCurrentDrawSurface() || surface == egl::getCurrentReadSurface())
+    {
+        surface->setPendingDestroy();
+    }
+    else
+    {
+        delete surface;
+        mSurfaceSet.erase(surface);
+    }
 }
 
 void Display::destroyContext(gl::Context *context)
 {
     glDestroyContext(context);
     mContextSet.erase(context);
 
-    if (mContextSet.empty() && mDevice && FAILED(mDevice->TestCooperativeLevel()))   // Last context of a lost device
+    if (mContextSet.empty() && mDevice && isDeviceLost())   // Last context of a lost device
     {
         for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
         {
             (*surface)->release();
         }	
     }
 }
 
-bool Display::isInitialized()
+bool Display::isInitialized() const
 {
     return mD3d9 != NULL && mConfigSet.size() > 0;
 }
 
 bool Display::isValidConfig(EGLConfig config)
 {
     return mConfigSet.get(config) != NULL;
 }
 
 bool Display::isValidContext(gl::Context *context)
 {
     return mContextSet.find(context) != mContextSet.end();
 }
 
 bool Display::isValidSurface(egl::Surface *surface)
 {
-    return mSurfaceSet.find(surface) != mSurfaceSet.end();
+    return mSurfaceSet.find(surface) != mSurfaceSet.end() && !surface->isPendingDestroy();
 }
 
 bool Display::hasExistingWindowSurface(HWND window)
 {
     for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
     {
         if ((*surface)->getWindowHandle() == window)
         {
@@ -514,16 +684,28 @@ IDirect3DDevice9 *Display::getDevice()
     return mDevice;
 }
 
 D3DCAPS9 Display::getDeviceCaps()
 {
     return mDeviceCaps;
 }
 
+bool Display::isDeviceLost()
+{
+    if (mDeviceEx)
+    {
+        return FAILED(mDeviceEx->CheckDeviceState(NULL));
+    }
+    else
+    {
+        return FAILED(mDevice->TestCooperativeLevel());
+    }
+}
+
 void Display::getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray)
 {
     for (int multiSampleIndex = 0; multiSampleIndex <= D3DMULTISAMPLE_16_SAMPLES; multiSampleIndex++)
     {
         HRESULT result = mD3d9->CheckDeviceMultiSampleType(mAdapter, mDeviceType, format,
                                                            TRUE, (D3DMULTISAMPLE_TYPE)multiSampleIndex, NULL);
 
         multiSampleArray[multiSampleIndex] = SUCCEEDED(result);
@@ -605,19 +787,24 @@ bool Display::getLuminanceTextureSupport
 bool Display::getLuminanceAlphaTextureSupport()
 {
     D3DDISPLAYMODE currentDisplayMode;
     mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
 
     return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A8L8));
 }
 
+bool Display::getNonPow2TextureSupport()
+{
+    return !(mDeviceCaps.TextureCaps & (D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_NONPOW2CONDITIONAL));
+}
+
 D3DPOOL Display::getBufferPool(DWORD usage) const
 {
-    if (mD3d9ex != NULL)
+    if (mD3d9Ex != NULL)
     {
         return D3DPOOL_DEFAULT;
     }
     else
     {
         if (!(usage & D3DUSAGE_DYNAMIC))
         {
             return D3DPOOL_MANAGED;
@@ -655,9 +842,48 @@ D3DPRESENT_PARAMETERS Display::getDefaul
     presentParameters.MultiSampleQuality = 0;
     presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
     presentParameters.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
     presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
     presentParameters.Windowed = TRUE;
 
     return presentParameters;
 }
+
+void Display::initExtensionString()
+{
+    mExtensionString += "EGL_ANGLE_query_surface_pointer ";
+
+    if (isD3d9ExDevice()) {
+        mExtensionString += "EGL_ANGLE_surface_d3d_texture_2d_share_handle ";
+        mExtensionString += "EGL_ANGLE_d3d_share_handle_client_buffer ";
+    }
+
+    std::string::size_type end = mExtensionString.find_last_not_of(' ');
+    if (end != std::string::npos)
+    {
+        mExtensionString.resize(end+1);
+    }
 }
+
+const char *Display::getExtensionString() const
+{
+    return mExtensionString.c_str();
+}
+
+// Only Direct3D 10 ready devices support all the necessary vertex texture formats.
+// We test this using D3D9 by checking support for the R16F format.
+bool Display::getVertexTextureSupport() const
+{
+    if (!isInitialized() || mDeviceCaps.PixelShaderVersion < D3DPS_VERSION(3, 0))
+    {
+        return false;
+    }
+
+    D3DDISPLAYMODE currentDisplayMode;
+    mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
+
+    HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, D3DFMT_R16F);
+
+    return SUCCEEDED(result);
+}
+
+}
--- a/gfx/angle/src/libEGL/Display.h
+++ b/gfx/angle/src/libEGL/Display.h
@@ -1,10 +1,10 @@
 //
-// 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.
 //
 
 // Display.h: Defines the egl::Display class, representing the abstract
 // display on which graphics are drawn. Implements EGLDisplay.
 // [EGL 1.4] section 2.1.2 page 3.
 
@@ -37,59 +37,64 @@ class Display
     void terminate();
 
     virtual void startScene();
     virtual void endScene();
 
     bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig);
     bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value);
 
-    egl::Surface *createWindowSurface(HWND window, EGLConfig config);
-    egl::Surface *createOffscreenSurface(int width, int height, EGLConfig config);
+    EGLSurface createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList);
+    EGLSurface createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList);
     EGLContext createContext(EGLConfig configHandle, const gl::Context *shareContext);
 
     void destroySurface(egl::Surface *surface);
     void destroyContext(gl::Context *context);
 
-    bool isInitialized();
+    bool isInitialized() const;
     bool isValidConfig(EGLConfig config);
     bool isValidContext(gl::Context *context);
     bool isValidSurface(egl::Surface *surface);
     bool hasExistingWindowSurface(HWND window);
 
     EGLint getMinSwapInterval();
     EGLint getMaxSwapInterval();
 
     virtual IDirect3DDevice9 *getDevice();
     virtual D3DCAPS9 getDeviceCaps();
+    bool isDeviceLost();
     virtual void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray);
     virtual bool getCompressedTextureSupport();
     virtual bool getEventQuerySupport();
     virtual bool getFloatTextureSupport(bool *filtering, bool *renderable);
     virtual bool getHalfFloatTextureSupport(bool *filtering, bool *renderable);
     virtual bool getLuminanceTextureSupport();
     virtual bool getLuminanceAlphaTextureSupport();
+    virtual bool getNonPow2TextureSupport();
+    virtual bool getVertexTextureSupport() const;
     virtual D3DPOOL getBufferPool(DWORD usage) const;
 
-    bool isD3d9exDevice() { return mD3d9ex != NULL; }
+    bool isD3d9ExDevice() { return mD3d9Ex != NULL; }
+    const char *getExtensionString() const;
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Display);
 
     D3DPRESENT_PARAMETERS getDefaultPresentParameters();
 
     const HDC mDc;
 
     HMODULE mD3d9Module;
     
     UINT mAdapter;
     D3DDEVTYPE mDeviceType;
     IDirect3D9 *mD3d9;  // Always valid after successful initialization.
-    IDirect3D9Ex *mD3d9ex;  // Might be null if D3D9Ex is not supported.
+    IDirect3D9Ex *mD3d9Ex;  // Might be null if D3D9Ex is not supported.
     IDirect3DDevice9 *mDevice;
+    IDirect3DDevice9Ex *mDeviceEx;  // Might be null if D3D9Ex is not supported.
     D3DCAPS9 mDeviceCaps;
     HWND mDeviceWindow;
 
     bool mSceneStarted;
     EGLint mMaxSwapInterval;
     EGLint mMinSwapInterval;
     
     typedef std::set<Surface*> SurfaceSet;
@@ -97,12 +102,15 @@ class Display
 
     ConfigSet mConfigSet;
 
     typedef std::set<gl::Context*> ContextSet;
     ContextSet mContextSet;
 
     bool createDevice();
     bool resetDevice();
+
+    void initExtensionString();
+    std::string mExtensionString;
 };
 }
 
 #endif   // INCLUDE_DISPLAY_H_
--- a/gfx/angle/src/libEGL/Makefile.in
+++ b/gfx/angle/src/libEGL/Makefile.in
@@ -86,16 +86,18 @@ CPPSRCS = \
   RemoveTree.cpp \
   ShaderLang.cpp \
   SymbolTable.cpp \
   VariableInfo.cpp \
   compilerdebug.cpp \
   ossource_win.cpp \
   util.cpp \
   ValidateLimitations.cpp \
+  ForLoopUnroll.cpp \
+  MapLongVariableNames.cpp \
   $(NULL)
 
 # flex/yacc generated files
 CPPSRCS += \
   glslang_lex.cpp \
   glslang_tab.cpp \
   $(NULL)
 
--- a/gfx/angle/src/libEGL/Surface.cpp
+++ b/gfx/angle/src/libEGL/Surface.cpp
@@ -8,66 +8,79 @@
 // such as the client area of a window, including any back buffers.
 // Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3.
 
 #include <tchar.h>
 
 #include "libEGL/Surface.h"
 
 #include "common/debug.h"
+#include "libGLESv2/Texture.h"
 
 #include "libEGL/main.h"
 #include "libEGL/Display.h"
 
 namespace egl
 {
 Surface::Surface(Display *display, const Config *config, HWND window) 
     : mDisplay(display), mConfig(config), mWindow(window)
 {
     mSwapChain = NULL;
     mDepthStencil = NULL;
     mRenderTarget = NULL;
     mOffscreenTexture = NULL;
     mShareHandle = NULL;
+    mTexture = NULL;
+    mTextureFormat = EGL_NO_TEXTURE;
+    mTextureTarget = EGL_NO_TEXTURE;
 
     mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING);   // FIXME: Determine actual pixel aspect ratio
     mRenderBuffer = EGL_BACK_BUFFER;
     mSwapBehavior = EGL_BUFFER_PRESERVED;
     mSwapInterval = -1;
     setSwapInterval(1);
 
+    mIsPendingDestroy = false;
+
     subclassWindow();
-    resetSwapChain();
 }
 
-Surface::Surface(Display *display, const Config *config, EGLint width, EGLint height)
-    : mDisplay(display), mWindow(NULL), mConfig(config), mWidth(width), mHeight(height)
+Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType)
+    : mDisplay(display), mWindow(NULL), mConfig(config), mShareHandle(shareHandle), mWidth(width), mHeight(height)
 {
     mSwapChain = NULL;
     mDepthStencil = NULL;
     mRenderTarget = NULL;
     mOffscreenTexture = NULL;
-    mShareHandle = NULL;
     mWindowSubclassed = false;
+    mTexture = NULL;
+    mTextureFormat = textureFormat;
+    mTextureTarget = textureType;
 
     mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING);   // FIXME: Determine actual pixel aspect ratio
     mRenderBuffer = EGL_BACK_BUFFER;
     mSwapBehavior = EGL_BUFFER_PRESERVED;
     mSwapInterval = -1;
     setSwapInterval(1);
 
-    resetSwapChain(width, height);
+    mIsPendingDestroy = false;
 }
 
 Surface::~Surface()
 {
     unsubclassWindow();
     release();
 }
 
+bool Surface::initialize()
+{
+    ASSERT(!mSwapChain && !mOffscreenTexture && !mDepthStencil);
+    return resetSwapChain();
+}
+
 void Surface::release()
 {
     if (mSwapChain)
     {
         mSwapChain->Release();
         mSwapChain = NULL;
     }
 
@@ -83,44 +96,50 @@ void Surface::release()
         mRenderTarget = NULL;
     }
 
     if (mOffscreenTexture)
     {
         mOffscreenTexture->Release();
         mOffscreenTexture = NULL;
     }
+
+    if (mTexture)
+    {
+        mTexture->releaseTexImage();
+        mTexture = NULL;
+    }
 }
 
-void Surface::resetSwapChain()
+bool Surface::resetSwapChain()
 {
-    if (!mWindow) {
-        resetSwapChain(mWidth, mHeight);
-        return;
+    if (!mWindow)
+    {
+        return resetSwapChain(mWidth, mHeight);
     }
 
     RECT windowRect;
     if (!GetClientRect(getWindowHandle(), &windowRect))
     {
         ASSERT(false);
 
         ERR("Could not retrieve the window dimensions");
-        return;
+        return false;
     }
 
-    resetSwapChain(windowRect.right - windowRect.left, windowRect.bottom - windowRect.top);
+    return resetSwapChain(windowRect.right - windowRect.left, windowRect.bottom - windowRect.top);
 }
 
-void Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
+bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
 {
     IDirect3DDevice9 *device = mDisplay->getDevice();
 
     if (device == NULL)
     {
-        return;
+        return false;
     }
 
     // Evict all non-render target textures to system memory and release all resources
     // before reallocating them to free up as much video memory as possible.
     device->EvictManagedResources();
     release();
 
     D3DPRESENT_PARAMETERS presentParameters = {0};
@@ -140,57 +159,61 @@ void Surface::resetSwapChain(int backbuf
     presentParameters.BackBufferWidth = backbufferWidth;
     presentParameters.BackBufferHeight = backbufferHeight;
 
     if (mWindow)
     {
         result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain);
     } else {
         HANDLE *pShareHandle = NULL;
-        if (mDisplay->isD3d9exDevice()) {
+        if (mDisplay->isD3d9ExDevice()) {
             pShareHandle = &mShareHandle;
         }
 
         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);
 
         ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result);
         release();
-        return error(EGL_BAD_ALLOC);
+        return error(EGL_BAD_ALLOC, false);
     }
 
-    result = device->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight,
-                                               presentParameters.AutoDepthStencilFormat, presentParameters.MultiSampleType,
-                                               presentParameters.MultiSampleQuality, FALSE, &mDepthStencil, NULL);
+    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);
 
         ERR("Could not create depthstencil surface for new swap chain: %08lX", result);
         release();
-        return error(EGL_BAD_ALLOC);
+        return error(EGL_BAD_ALLOC, false);
     }
 
     if (mWindow) {
         mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mRenderTarget);
         InvalidateRect(mWindow, NULL, FALSE);
     } else {
         mOffscreenTexture->GetSurfaceLevel(0, &mRenderTarget);
     }
 
     mWidth = presentParameters.BackBufferWidth;
     mHeight = presentParameters.BackBufferHeight;
 
     mPresentIntervalDirty = false;
+    return true;
 }
 
 HWND Surface::getWindowHandle()
 {
     return mWindow;
 }
 
 
@@ -342,23 +365,67 @@ IDirect3DSurface9 *Surface::getDepthSten
     if (mDepthStencil)
     {
         mDepthStencil->AddRef();
     }
 
     return mDepthStencil;
 }
 
+IDirect3DTexture9 *Surface::getOffscreenTexture()
+{
+    if (mOffscreenTexture)
+    {
+        mOffscreenTexture->AddRef();
+    }
+
+    return mOffscreenTexture;
+}
+
 void Surface::setSwapInterval(EGLint interval)
 {
     if (mSwapInterval == interval)
     {
         return;
     }
     
     mSwapInterval = interval;
     mSwapInterval = std::max(mSwapInterval, mDisplay->getMinSwapInterval());
     mSwapInterval = std::min(mSwapInterval, mDisplay->getMaxSwapInterval());
 
     mPresentInterval = convertInterval(mSwapInterval);
     mPresentIntervalDirty = true;
 }
+
+EGLenum Surface::getTextureFormat() const
+{
+    return mTextureFormat;
 }
+
+EGLenum Surface::getTextureTarget() const
+{
+    return mTextureTarget;
+}
+
+void Surface::setBoundTexture(gl::Texture2D *texture)
+{
+    mTexture = texture;
+}
+
+gl::Texture2D *Surface::getBoundTexture() const
+{
+    return mTexture;
+}
+
+D3DFORMAT Surface::getFormat() const
+{
+    return mConfig->mRenderTargetFormat;
+}
+
+void Surface::setPendingDestroy() {
+    mIsPendingDestroy = true;
+}
+
+bool Surface::isPendingDestroy() const {
+    return mIsPendingDestroy;
+}
+
+}
--- a/gfx/angle/src/libEGL/Surface.h
+++ b/gfx/angle/src/libEGL/Surface.h
@@ -12,79 +12,98 @@
 #define INCLUDE_SURFACE_H_
 
 #define EGLAPI
 #include <EGL/egl.h>
 #include <d3d9.h>
 
 #include "common/angleutils.h"
 
+namespace gl
+{
+class Texture2D;
+}
+
 namespace egl
 {
 class Display;
 class Config;
 
 class Surface
 {
   public:
     Surface(Display *display, const egl::Config *config, HWND window);
-    Surface(Display *display, const egl::Config *config, EGLint width, EGLint height);
+    Surface(Display *display, const egl::Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureTarget);
 
     ~Surface();
 
+    bool initialize();
     void release();
-    void resetSwapChain();
+    bool resetSwapChain();
 
     HWND getWindowHandle();
     bool swap();
 
     virtual EGLint getWidth() const;
     virtual EGLint getHeight() const;
 
     virtual IDirect3DSurface9 *getRenderTarget();
     virtual IDirect3DSurface9 *getDepthStencil();
+    virtual IDirect3DTexture9 *getOffscreenTexture();
 
     HANDLE getShareHandle() { return mShareHandle; }
 
     void setSwapInterval(EGLint interval);
     bool checkForOutOfDateSwapChain();   // Returns true if swapchain changed due to resize or interval update
 
+    virtual EGLenum getTextureFormat() const;
+    virtual EGLenum getTextureTarget() const;
+    virtual D3DFORMAT getFormat() const;
+
+    virtual void setBoundTexture(gl::Texture2D *texture);
+    virtual gl::Texture2D *getBoundTexture() const;
+
+    void setPendingDestroy();
+    bool isPendingDestroy() const;
+
 private:
     DISALLOW_COPY_AND_ASSIGN(Surface);
 
     Display *const mDisplay;
     IDirect3DSwapChain9 *mSwapChain;
     IDirect3DSurface9 *mDepthStencil;
     IDirect3DSurface9* mRenderTarget;
     IDirect3DTexture9* mOffscreenTexture;
 
     HANDLE mShareHandle;
+    bool mIsPendingDestroy;
 
     void subclassWindow();
     void unsubclassWindow();
-    void resetSwapChain(int backbufferWidth, int backbufferHeight);
+    bool resetSwapChain(int backbufferWidth, int backbufferHeight);
     static DWORD convertInterval(EGLint interval);
 
     const HWND mWindow;            // Window that the surface is created for.
     bool mWindowSubclassed;        // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking
     const egl::Config *mConfig;    // EGL config surface was created with
     EGLint mHeight;                // Height of surface
     EGLint mWidth;                 // Width of surface
 //  EGLint horizontalResolution;   // Horizontal dot pitch
 //  EGLint verticalResolution;     // Vertical dot pitch
 //  EGLBoolean largestPBuffer;     // If true, create largest pbuffer possible
 //  EGLBoolean mipmapTexture;      // True if texture has mipmaps
 //  EGLint mipmapLevel;            // Mipmap level to render to
 //  EGLenum multisampleResolve;    // Multisample resolve behavior
     EGLint mPixelAspectRatio;      // Display aspect ratio
     EGLenum mRenderBuffer;         // Render buffer
     EGLenum mSwapBehavior;         // Buffer swap behavior
-//  EGLenum textureFormat;         // Format of texture: RGB, RGBA, or no texture
-//  EGLenum textureTarget;         // Type of texture: 2D or no texture
+    EGLenum mTextureFormat;        // Format of texture: RGB, RGBA, or no texture
+    EGLenum mTextureTarget;        // Type of texture: 2D or no texture
 //  EGLenum vgAlphaFormat;         // Alpha format for OpenVG
 //  EGLenum vgColorSpace;          // Color space for OpenVG
     EGLint mSwapInterval;
     DWORD mPresentInterval;
     bool mPresentIntervalDirty;
+    gl::Texture2D *mTexture;
 };
 }
 
 #endif   // INCLUDE_SURFACE_H_
--- a/gfx/angle/src/libEGL/libEGL.cpp
+++ b/gfx/angle/src/libEGL/libEGL.cpp
@@ -6,69 +6,70 @@
 
 // libEGL.cpp: Implements the exported EGL functions.
 
 #include <exception>
 
 #include "common/debug.h"
 #include "common/version.h"
 #include "libGLESv2/Context.h"
+#include "libGLESv2/Texture.h"
 
 #include "libEGL/main.h"
 #include "libEGL/Display.h"
 
 
-bool validate(egl::Display *display)
+bool validateDisplay(egl::Display *display)
 {
     if (display == EGL_NO_DISPLAY)
     {
         return error(EGL_BAD_DISPLAY, false);
     }
 
     if (!display->isInitialized())
     {
         return error(EGL_NOT_INITIALIZED, false);
     }
 
     return true;
 }
 
-bool validate(egl::Display *display, EGLConfig config)
+bool validateConfig(egl::Display *display, EGLConfig config)
 {
-    if (!validate(display))
+    if (!validateDisplay(display))
     {
         return false;
     }
 
     if (!display->isValidConfig(config))
     {
         return error(EGL_BAD_CONFIG, false);
     }
 
     return true;
 }
 
-bool validate(egl::Display *display, gl::Context *context)
+bool validateContext(egl::Display *display, gl::Context *context)
 {
-    if (!validate(display))
+    if (!validateDisplay(display))
     {
         return false;
     }
 
     if (!display->isValidContext(context))
     {
         return error(EGL_BAD_CONTEXT, false);
     }
 
     return true;
 }
 
-bool validate(egl::Display *display, egl::Surface *surface)
+bool validateSurface(egl::Display *display, egl::Surface *surface)
 {
-    if (!validate(display))
+    if (!validateDisplay(display))
     {
         return false;
     }
 
     if (!display->isValidSurface(surface))
     {
         return error(EGL_BAD_SURFACE, false);
     }
@@ -179,27 +180,27 @@ EGLBoolean __stdcall eglTerminate(EGLDis
 const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name)
 {
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint name = %d)", dpy, name);
 
     try
     {
         egl::Display *display = static_cast<egl::Display*>(dpy);
 
-        if (!validate(display))
+        if (!validateDisplay(display))
         {
             return NULL;
         }
 
         switch (name)
         {
           case EGL_CLIENT_APIS:
             return success("OpenGL_ES");
           case EGL_EXTENSIONS:
-            return success("EGL_ANGLE_query_surface_pointer EGL_ANGLE_surface_d3d_share_handle");
+            return display->getExtensionString();
           case EGL_VENDOR:
             return success("Google Inc.");
           case EGL_VERSION:
             return success("1.4 (ANGLE "VERSION_STRING")");
         }
 
         return error(EGL_BAD_PARAMETER, (const char*)NULL);
     }
@@ -216,17 +217,17 @@ EGLBoolean __stdcall eglGetConfigs(EGLDi
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig *configs = 0x%0.8p, "
           "EGLint config_size = %d, EGLint *num_config = 0x%0.8p)",
           dpy, configs, config_size, num_config);
 
     try
     {
         egl::Display *display = static_cast<egl::Display*>(dpy);
 
-        if (!validate(display))
+        if (!validateDisplay(display))
         {
             return EGL_FALSE;
         }
 
         if (!num_config)
         {
             return error(EGL_BAD_PARAMETER, EGL_FALSE);
         }
@@ -253,17 +254,17 @@ EGLBoolean __stdcall eglChooseConfig(EGL
     EVENT("(EGLDisplay dpy = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p, "
           "EGLConfig *configs = 0x%0.8p, EGLint config_size = %d, EGLint *num_config = 0x%0.8p)",
           dpy, attrib_list, configs, config_size, num_config);
 
     try
     {
         egl::Display *display = static_cast<egl::Display*>(dpy);
 
-        if (!validate(display))
+        if (!validateDisplay(display))
         {
             return EGL_FALSE;
         }
 
         if (!num_config)
         {
             return error(EGL_BAD_PARAMETER, EGL_FALSE);
         }
@@ -291,17 +292,17 @@ EGLBoolean __stdcall eglGetConfigAttrib(
 {
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
           dpy, config, attribute, value);
 
     try
     {
         egl::Display *display = static_cast<egl::Display*>(dpy);
 
-        if (!validate(display, config))
+        if (!validateConfig(display, config))
         {
             return EGL_FALSE;
         }
 
         if (!display->getConfigAttrib(config, attribute, value))
         {
             return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
         }
@@ -320,65 +321,29 @@ EGLSurface __stdcall eglCreateWindowSurf
 {
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativeWindowType win = 0x%0.8p, "
           "const EGLint *attrib_list = 0x%0.8p)", dpy, config, win, attrib_list);
 
     try
     {
         egl::Display *display = static_cast<egl::Display*>(dpy);
 
-        if (!validate(display, config))
+        if (!validateConfig(display, config))
         {
             return EGL_NO_SURFACE;
         }
 
         HWND window = (HWND)win;
 
         if (!IsWindow(window))
         {
             return error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
         }
 
-        if (attrib_list)
-        {
-            while (*attrib_list != EGL_NONE)
-            {
-                switch (attrib_list[0])
-                {
-                  case EGL_RENDER_BUFFER:
-                    switch (attrib_list[1])
-                    {
-                      case EGL_BACK_BUFFER:
-                        break;
-                      case EGL_SINGLE_BUFFER:
-                        return error(EGL_BAD_MATCH, EGL_NO_SURFACE);   // Rendering directly to front buffer not supported
-                      default:
-                        return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-                    }
-                    break;
-                  case EGL_VG_COLORSPACE:
-                    return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
-                  case EGL_VG_ALPHA_FORMAT:
-                    return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
-                  default:
-                    return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-                }
-
-                attrib_list += 2;
-            }
-        }
-
-        if (display->hasExistingWindowSurface(window))
-        {
-            return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
-        }
-
-        EGLSurface surface = (EGLSurface)display->createWindowSurface(window, config);
-
-        return success(surface);
+        return display->createWindowSurface(window, config, attrib_list);
     }
     catch(std::bad_alloc&)
     {
         return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
     }
 
     return EGL_NO_SURFACE;
 }
@@ -386,71 +351,23 @@ EGLSurface __stdcall eglCreateWindowSurf
 EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
 {
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)",
           dpy, config, attrib_list);
 
     try
     {
         egl::Display *display = static_cast<egl::Display*>(dpy);
-        EGLint width = 0, height = 0;
 
-        if (!validate(display, config))
+        if (!validateConfig(display, config))
         {
             return EGL_NO_SURFACE;
         }
 
-        if (attrib_list)
-        {
-            while (*attrib_list != EGL_NONE)
-            {
-                switch (attrib_list[0])
-                {
-                  case EGL_WIDTH:
-                    width = attrib_list[1];
-                    break;
-                  case EGL_HEIGHT:
-                    height = attrib_list[1];
-                    break;
-                  case EGL_LARGEST_PBUFFER:
-                    if (attrib_list[1] != EGL_FALSE)
-                      UNIMPLEMENTED(); // FIXME
-                    break;
-                  case EGL_TEXTURE_FORMAT:
-                  case EGL_TEXTURE_TARGET:
-                    switch (attrib_list[1])
-                    {
-                      case EGL_NO_TEXTURE:
-                        break;
-                      default:
-                        return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-                    }
-                    break;
-                  case EGL_MIPMAP_TEXTURE:
-                    if (attrib_list[1] != EGL_FALSE)
-                      return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-                    break;
-                  case EGL_VG_COLORSPACE:
-                    return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
-                  case EGL_VG_ALPHA_FORMAT:
-                    return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
-                  default:
-                    return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-                }
-
-                attrib_list += 2;
-            }
-        }
-
-        if (width == 0 || height == 0)
-          return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-
-        EGLSurface surface = (EGLSurface)display->createOffscreenSurface(width, height, config);
-
-        return success(surface);
+        return display->createOffscreenSurface(config, NULL, attrib_list);
     }
     catch(std::bad_alloc&)
     {
         return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
     }
 
     return EGL_NO_SURFACE;
 }
@@ -459,17 +376,17 @@ EGLSurface __stdcall eglCreatePixmapSurf
 {
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativePixmapType pixmap = 0x%0.8p, "
           "const EGLint *attrib_list = 0x%0.8p)", dpy, config, pixmap, attrib_list);
 
     try
     {
         egl::Display *display = static_cast<egl::Display*>(dpy);
 
-        if (!validate(display, config))
+        if (!validateConfig(display, config))
         {
             return EGL_NO_SURFACE;
         }
 
         UNIMPLEMENTED();   // FIXME
 
         return success(EGL_NO_SURFACE);
     }
@@ -483,18 +400,19 @@ EGLSurface __stdcall eglCreatePixmapSurf
 
 EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
 {
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
 
     try
     {
         egl::Display *display = static_cast<egl::Display*>(dpy);
+        egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
 
-        if (!validate(display))
+        if (!validateSurface(display, eglSurface))
         {
             return EGL_FALSE;
         }
 
         if (surface == EGL_NO_SURFACE)
         {
             return error(EGL_BAD_SURFACE, EGL_FALSE);
         }
@@ -514,29 +432,28 @@ EGLBoolean __stdcall eglDestroySurface(E
 EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
 {
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
           dpy, surface, attribute, value);
 
     try
     {
         egl::Display *display = static_cast<egl::Display*>(dpy);
+        egl::Surface *eglSurface = (egl::Surface*)surface;
 
-        if (!validate(display))
+        if (!validateSurface(display, eglSurface))
         {
             return EGL_FALSE;
         }
 
         if (surface == EGL_NO_SURFACE)
         {
             return error(EGL_BAD_SURFACE, EGL_FALSE);
         }
 
-        egl::Surface *eglSurface = (egl::Surface*)surface;
-
         switch (attribute)
         {
           case EGL_VG_ALPHA_FORMAT:
             UNIMPLEMENTED();   // FIXME
             break;
           case EGL_VG_COLORSPACE:
             UNIMPLEMENTED();   // FIXME
             break;
@@ -599,32 +516,31 @@ EGLBoolean __stdcall eglQuerySurface(EGL
 EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value)
 {
     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, void **value = 0x%0.8p)",
           dpy, surface, attribute, value);
 
     try
     {
         egl::Display *display = static_cast<egl::Display*>(dpy);
+        egl::Surface *eglSurface = (egl::Surface*)surface;
 
-        if (!validate(display))
+        if (!validateSurface(display, eglSurface))
         {
             return EGL_FALSE;
         }
 
         if (surface == EGL_NO_SURFACE)
         {
             return error(EGL_BAD_SURFACE, EGL_FALSE);
         }
 
-        egl::Surface *eglSurface = (egl::Surface*)surface;
-
         switch (attribute)
         {
-          case EGL_D3D_TEXTURE_SHARE_HANDLE_ANGLE:
+          case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
             *value = (void*) eglSurface->getShareHandle();
             break;
           default:
             return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
         }
 
         return success(EGL_TRUE);
     }
@@ -724,24 +640,27 @@ EGLSurface __stdcall eglCreatePbufferFro
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = 0x%0.8p, "
           "EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)",
           dpy, buftype, buffer, config, attrib_list);
 
     try
     {
         egl::Display *display = static_cast<egl::Display*>(dpy);
 
-        if (!validate(display, config))
+        if (!validateConfig(display, config))
         {
             return EGL_NO_SURFACE;
         }
 
-        UNIMPLEMENTED();   // FIXME
+        if (buftype != EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE || !buffer)
+        {
+            return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
+        }
 
-        return success(EGL_NO_SURFACE);
+        return display->createOffscreenSurface(config, (HANDLE)buffer, attrib_list);
     }
     catch(std::bad_alloc&)
     {
         return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
     }
 
     return EGL_NO_SURFACE;
 }
@@ -749,18 +668,19 @@ EGLSurface __stdcall eglCreatePbufferFro
 EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
 {
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint value = %d)",
           dpy, surface, attribute, value);
 
     try
     {
         egl::Display *display = static_cast<egl::Display*>(dpy);
+        egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
 
-        if (!validate(display))
+        if (!validateSurface(display, eglSurface))
         {
             return EGL_FALSE;
         }
 
         UNIMPLEMENTED();   // FIXME
 
         return success(EGL_TRUE);
     }
@@ -774,50 +694,92 @@ EGLBoolean __stdcall eglSurfaceAttrib(EG
 
 EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
 {
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
 
     try
     {
         egl::Display *display = static_cast<egl::Display*>(dpy);
+        egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
 
-        if (!validate(display))
+        if (!validateSurface(display, eglSurface))
         {
             return EGL_FALSE;
         }
 
-        // FIXME - need implementation
+        if (buffer != EGL_BACK_BUFFER)
+        {
+            return error(EGL_BAD_PARAMETER, EGL_FALSE);
+        }
+
+        if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())
+        {
+            return error(EGL_BAD_SURFACE, EGL_FALSE);
+        }
 
-        return success(EGL_FALSE);
+        if (eglSurface->getBoundTexture())
+        {
+            return error(EGL_BAD_ACCESS, EGL_FALSE);
+        }
+
+        if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
+        {
+            return error(EGL_BAD_MATCH, EGL_FALSE);
+        }
+
+        glBindTexImage(eglSurface);
+
+        return success(EGL_TRUE);
     }
     catch(std::bad_alloc&)
     {
         return error(EGL_BAD_ALLOC, EGL_FALSE);
     }
 
     return EGL_FALSE;
 }
 
 EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
 {
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
 
     try
     {
         egl::Display *display = static_cast<egl::Display*>(dpy);
+        egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
 
-        if (!validate(display))
+        if (!validateSurface(display, eglSurface))
         {
             return EGL_FALSE;
         }
 
-        // FIXME - need implementation
+        if (buffer != EGL_BACK_BUFFER)
+        {
+            return error(EGL_BAD_PARAMETER, EGL_FALSE);
+        }
+
+        if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())
+        {
+            return error(EGL_BAD_SURFACE, EGL_FALSE);
+        }
 
-        return success(EGL_FALSE);
+        if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
+        {
+            return error(EGL_BAD_MATCH, EGL_FALSE);
+        }
+
+        gl::Texture2D *texture = eglSurface->getBoundTexture();
+
+        if (texture)
+        {
+            texture->releaseTexImage();
+        }
+
+        return success(EGL_TRUE);
     }
     catch(std::bad_alloc&)
     {
         return error(EGL_BAD_ALLOC, EGL_FALSE);
     }
 
     return EGL_FALSE;
 }
@@ -825,17 +787,17 @@ EGLBoolean __stdcall eglReleaseTexImage(
 EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval)
 {
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint interval = %d)", dpy, interval);
 
     try
     {
         egl::Display *display = static_cast<egl::Display*>(dpy);
 
-        if (!validate(display))
+        if (!validateDisplay(display))
         {
             return EGL_FALSE;
         }
 
         egl::Surface *draw_surface = static_cast<egl::Surface*>(egl::getCurrentDrawSurface());
 
         if (draw_surface == NULL)
         {
@@ -880,17 +842,17 @@ EGLContext __stdcall eglCreateContext(EG
 
         if (client_version != 2)
         {
             return error(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
         }
 
         egl::Display *display = static_cast<egl::Display*>(dpy);
 
-        if (!validate(display, config))
+        if (!validateConfig(display, config))
         {
             return EGL_NO_CONTEXT;
         }
 
         EGLContext context = display->createContext(config, static_cast<gl::Context*>(share_context));
 
         return success(context);
     }
@@ -904,28 +866,29 @@ EGLContext __stdcall eglCreateContext(EG
 
 EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
 {
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, ctx);
 
     try
     {
         egl::Display *display = static_cast<egl::Display*>(dpy);
+        gl::Context *context = static_cast<gl::Context*>(ctx);
 
-        if (!validate(display))
+        if (!validateContext(display, context))
         {
             return EGL_FALSE;
         }
 
         if (ctx == EGL_NO_CONTEXT)
         {
             return error(EGL_BAD_CONTEXT, EGL_FALSE);
         }
 
-        display->destroyContext((gl::Context*)ctx);
+        display->destroyContext(context);
 
         return success(EGL_TRUE);
     }
     catch(std::bad_alloc&)
     {
         return error(EGL_BAD_ALLOC, EGL_FALSE);
     }
 
@@ -938,43 +901,58 @@ EGLBoolean __stdcall eglMakeCurrent(EGLD
           dpy, draw, read, ctx);
 
     try
     {
         egl::Display *display = static_cast<egl::Display*>(dpy);
         gl::Context *context = static_cast<gl::Context*>(ctx);
         IDirect3DDevice9 *device = display->getDevice();
 
-        if (!device || FAILED(device->TestCooperativeLevel()))
+        if (!device || display->isDeviceLost())
         {
             return error(EGL_CONTEXT_LOST, EGL_FALSE);
         }
 
-        if (ctx != EGL_NO_CONTEXT && !validate(display, context))
+        if (ctx != EGL_NO_CONTEXT && !validateContext(display, context))
         {
             return EGL_FALSE;
         }
 
-        if ((draw != EGL_NO_SURFACE && !validate(display, static_cast<egl::Surface*>(draw))) ||
-            (read != EGL_NO_SURFACE && !validate(display, static_cast<egl::Surface*>(read))))
+        if ((draw != EGL_NO_SURFACE && !validateSurface(display, static_cast<egl::Surface*>(draw))) ||
+            (read != EGL_NO_SURFACE && !validateSurface(display, static_cast<egl::Surface*>(read))))
         {
             return EGL_FALSE;
         }
 
         if (draw != read)
         {
             UNIMPLEMENTED();   // FIXME
         }
 
+        egl::Surface* previousDraw = static_cast<egl::Surface*>(egl::getCurrentDrawSurface());
+        egl::Surface* previousRead = static_cast<egl::Surface*>(egl::getCurrentReadSurface());
+
         egl::setCurrentDisplay(dpy);
         egl::setCurrentDrawSurface(draw);
         egl::setCurrentReadSurface(read);
 
         glMakeCurrent(context, display, static_cast<egl::Surface*>(draw));
 
+        // If the previous surfaces are still current, this might just flag
+        // them as pending destruction again, deferring destruction to a future
+        // eglMakeCurrent or eglTerminate call.
+        if (previousDraw && previousDraw->isPendingDestroy())
+        {
+            eglDestroySurface(dpy, previousDraw);
+        }
+        if (previousRead && previousRead != previousDraw && previousRead->isPendingDestroy())
+        {
+            eglDestroySurface(dpy, previousRead);
+        }
+
         return success(EGL_TRUE);
     }
     catch(std::bad_alloc&)
     {
         return error(EGL_BAD_ALLOC, EGL_FALSE);
     }
 
     return EGL_FALSE;
@@ -1048,18 +1026,19 @@ EGLDisplay __stdcall eglGetCurrentDispla
 EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
 {
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
           dpy, ctx, attribute, value);
 
     try
     {
         egl::Display *display = static_cast<egl::Display*>(dpy);
+        gl::Context *context = static_cast<gl::Context*>(ctx);
 
-        if (!validate(display))
+        if (!validateContext(display, context))
         {
             return EGL_FALSE;
         }
 
         UNIMPLEMENTED();   // FIXME
 
         return success(0);
     }
@@ -1109,29 +1088,28 @@ EGLBoolean __stdcall eglWaitNative(EGLin
 
 EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
 {
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
 
     try
     {
         egl::Display *display = static_cast<egl::Display*>(dpy);
+        egl::Surface *eglSurface = (egl::Surface*)surface;
 
-        if (!validate(display))
+        if (!validateSurface(display, eglSurface))
         {
             return EGL_FALSE;
         }
 
         if (surface == EGL_NO_SURFACE)
         {
             return error(EGL_BAD_SURFACE, EGL_FALSE);
         }
 
-        egl::Surface *eglSurface = (egl::Surface*)surface;
-
         if (eglSurface->swap())
         {
             return success(EGL_TRUE);
         }
     }
     catch(std::bad_alloc&)
     {
         return error(EGL_BAD_ALLOC, EGL_FALSE);
@@ -1142,18 +1120,19 @@ EGLBoolean __stdcall eglSwapBuffers(EGLD
 
 EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
 {
     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLNativePixmapType target = 0x%0.8p)", dpy, surface, target);
 
     try
     {
         egl::Display *display = static_cast<egl::Display*>(dpy);
+        egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
 
-        if (!validate(display))
+        if (!validateSurface(display, eglSurface))
         {
             return EGL_FALSE;
         }
 
         UNIMPLEMENTED();   // FIXME
 
         return success(0);
     }
--- a/gfx/angle/src/libGLESv2/Blit.cpp
+++ b/gfx/angle/src/libGLESv2/Blit.cpp
@@ -150,39 +150,47 @@ void Blit::initGeometry()
         -1, -1,
         -1,  1,
          1, -1,
          1,  1
     };
 
     IDirect3DDevice9 *device = getDevice();
 
-    HRESULT hr = device->CreateVertexBuffer(sizeof(quad), D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &mQuadVertexBuffer, NULL);
+    HRESULT result = device->CreateVertexBuffer(sizeof(quad), D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &mQuadVertexBuffer, NULL);
 
-    if (FAILED(hr))
+    if (FAILED(result))
     {
-        ASSERT(hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
+        ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
         return error(GL_OUT_OF_MEMORY);
     }
 
-    void *lockPtr;
-    mQuadVertexBuffer->Lock(0, 0, &lockPtr, 0);
+    void *lockPtr = NULL;
+    result = mQuadVertexBuffer->Lock(0, 0, &lockPtr, 0);
+
+    if (FAILED(result) || lockPtr == NULL)
+    {
+        ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+        return error(GL_OUT_OF_MEMORY);
+    }
+
     memcpy(lockPtr, quad, sizeof(quad));
     mQuadVertexBuffer->Unlock();
 
     static const D3DVERTEXELEMENT9 elements[] =
     {
         { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
         D3DDECL_END()
     };
 
-    hr = device->CreateVertexDeclaration(elements, &mQuadVertexDeclaration);
-    if (FAILED(hr))
+    result = device->CreateVertexDeclaration(elements, &mQuadVertexDeclaration);
+
+    if (FAILED(result))
     {
-        ASSERT(hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
+        ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
         return error(GL_OUT_OF_MEMORY);
     }
 }
 
 template <class D3DShaderType>
 bool Blit::setShader(ShaderId source, const char *profile,
                      HRESULT (WINAPI IDirect3DDevice9::*createShader)(const DWORD *, D3DShaderType**),
                      HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*))
@@ -282,16 +290,44 @@ bool Blit::boxFilter(IDirect3DSurface9 *
 
     texture->Release();
 
     restoreState();
 
     return true;
 }
 
+bool Blit::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest)
+{
+    IDirect3DDevice9 *device = getDevice();
+
+    D3DSURFACE_DESC sourceDesc;
+    D3DSURFACE_DESC destDesc;
+    source->GetDesc(&sourceDesc);
+    dest->GetDesc(&destDesc);
+
+    if (sourceDesc.Format == destDesc.Format && destDesc.Usage & D3DUSAGE_RENDERTARGET)   // Can use StretchRect
+    {
+        RECT destRect = {xoffset, yoffset, xoffset + (sourceRect.right - sourceRect.left), yoffset + (sourceRect.bottom - sourceRect.top)};
+        HRESULT result = device->StretchRect(source, &sourceRect, dest, &destRect, D3DTEXF_POINT);
+
+        if (FAILED(result))
+        {
+            ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+            return error(GL_OUT_OF_MEMORY, false);
+        }
+    }
+    else
+    {
+        return formatConvert(source, sourceRect, destFormat, xoffset, yoffset, dest);
+    }
+
+    return true;
+}
+
 bool Blit::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest)
 {
     IDirect3DTexture9 *texture = copySurfaceToTexture(source, sourceRect);
     if (!texture)
     {
         return false;
     }
 
--- a/gfx/angle/src/libGLESv2/Blit.h
+++ b/gfx/angle/src/libGLESv2/Blit.h
@@ -25,16 +25,20 @@ class Context;
 class Blit
 {
   public:
     explicit Blit(Context *context);
     ~Blit();
 
     // Copy from source surface to dest surface.
     // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left)
+    bool copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest);
+
+    // Copy from source surface to dest surface.
+    // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left)
     // source is interpreted as RGBA and destFormat specifies the desired result format. For example, if destFormat = GL_RGB, the alpha channel will be forced to 0.
     bool formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest);
 
     // 2x2 box filter sample from source to dest.
     // Requires that source is RGB(A) and dest has the same format as source.
     bool boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest);
 
   private:
--- a/gfx/angle/src/libGLESv2/Buffer.cpp
+++ b/gfx/angle/src/libGLESv2/Buffer.cpp
@@ -6,37 +6,38 @@
 
 // Buffer.cpp: Implements the gl::Buffer class, representing storage of vertex and/or
 // index data. Implements GL buffer objects and related functionality.
 // [OpenGL ES 2.0.24] section 2.9 page 21.
 
 #include "libGLESv2/Buffer.h"
 
 #include "libGLESv2/main.h"
-#include "libGLESv2/geometry/VertexDataManager.h"
-#include "libGLESv2/geometry/IndexDataManager.h"
+#include "libGLESv2/VertexDataManager.h"
+#include "libGLESv2/IndexDataManager.h"
 
 namespace gl
 {
 
 Buffer::Buffer(GLuint id) : RefCountObject(id)
 {
     mContents = NULL;
     mSize = 0;
     mUsage = GL_DYNAMIC_DRAW;
 
-    mVertexBuffer = NULL;
-    mIndexBuffer = NULL;
+    mStaticVertexBuffer = NULL;
+    mStaticIndexBuffer = NULL;
+    mUnmodifiedDataUse = 0;
 }
 
 Buffer::~Buffer()
 {
     delete[] mContents;
-    delete mVertexBuffer;
-    delete mIndexBuffer;
+    delete mStaticVertexBuffer;
+    delete mStaticIndexBuffer;
 }
 
 void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
 {
     if (size == 0)
     {
         delete[] mContents;
         mContents = NULL;
@@ -55,52 +56,60 @@ void Buffer::bufferData(const void *data
 
     mSize = size;
     mUsage = usage;
 
     invalidateStaticData();
 
     if (usage == GL_STATIC_DRAW)
     {
-        mVertexBuffer = new StaticVertexBuffer(getDevice());
-        mIndexBuffer = new StaticIndexBuffer(getDevice());
+        mStaticVertexBuffer = new StaticVertexBuffer(getDevice());
+        mStaticIndexBuffer = new StaticIndexBuffer(getDevice());
     }
 }
 
 void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset)
 {
     memcpy(mContents + offset, data, size);
-
-    if ((mVertexBuffer && mVertexBuffer->size() != 0) || (mIndexBuffer && mIndexBuffer->size() != 0))
+    
+    if ((mStaticVertexBuffer && mStaticVertexBuffer->size() != 0) || (mStaticIndexBuffer && mStaticIndexBuffer->size() != 0))
     {
         invalidateStaticData();
+    }
+}
 
-        if (mUsage == GL_STATIC_DRAW)
+StaticVertexBuffer *Buffer::getStaticVertexBuffer()
+{
+    return mStaticVertexBuffer;
+}
+
+StaticIndexBuffer *Buffer::getStaticIndexBuffer()
+{
+    return mStaticIndexBuffer;
+}
+
+void Buffer::invalidateStaticData()
+{
+    delete mStaticVertexBuffer;
+    mStaticVertexBuffer = NULL;
+
+    delete mStaticIndexBuffer;
+    mStaticIndexBuffer = NULL;
+
+    mUnmodifiedDataUse = 0;
+}
+
+// Creates static buffers if sufficient used data has been left unmodified
+void Buffer::promoteStaticUsage(int dataSize)
+{
+    if (!mStaticVertexBuffer && !mStaticIndexBuffer)
+    {
+        mUnmodifiedDataUse += dataSize;
+
+        if (mUnmodifiedDataUse > 3 * mSize)
         {
-            // If applications update the buffer data after it has already been used in a draw call,
-            // it most likely isn't used as a static buffer so we should fall back to streaming usage
-            // for best performance. So ignore the usage hint and don't create new static buffers.
-        //  mVertexBuffer = new StaticVertexBuffer(getDevice());
-        //  mIndexBuffer = new StaticIndexBuffer(getDevice());
+            mStaticVertexBuffer = new StaticVertexBuffer(getDevice());
+            mStaticIndexBuffer = new StaticIndexBuffer(getDevice());
         }
     }
 }
 
-StaticVertexBuffer *Buffer::getVertexBuffer()
-{
-    return mVertexBuffer;
 }
-
-StaticIndexBuffer *Buffer::getIndexBuffer()
-{
-    return mIndexBuffer;
-}
-
-void Buffer::invalidateStaticData()
-{
-    delete mVertexBuffer;
-    mVertexBuffer = NULL;
-
-    delete mIndexBuffer;
-    mIndexBuffer = NULL;
-}
-
-}
--- a/gfx/angle/src/libGLESv2/Buffer.h
+++ b/gfx/angle/src/libGLESv2/Buffer.h
@@ -34,26 +34,28 @@ class Buffer : public RefCountObject
 
     void bufferData(const void *data, GLsizeiptr size, GLenum usage);
     void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);
 
     void *data() { return mContents; }
     size_t size() const { return mSize; }
     GLenum usage() const { return mUsage; }
 
-    StaticVertexBuffer *getVertexBuffer();
-    StaticIndexBuffer *getIndexBuffer();
+    StaticVertexBuffer *getStaticVertexBuffer();
+    StaticIndexBuffer *getStaticIndexBuffer();
     void invalidateStaticData();
+    void promoteStaticUsage(int dataSize);
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Buffer);
 
     GLubyte *mContents;
     size_t mSize;
     GLenum mUsage;
 
-    StaticVertexBuffer *mVertexBuffer;
-    StaticIndexBuffer *mIndexBuffer;
+    StaticVertexBuffer *mStaticVertexBuffer;
+    StaticIndexBuffer *mStaticIndexBuffer;
+    size_t mUnmodifiedDataUse;
 };
 
 }
 
 #endif   // LIBGLESV2_BUFFER_H_
--- a/gfx/angle/src/libGLESv2/Context.cpp
+++ b/gfx/angle/src/libGLESv2/Context.cpp
@@ -1,10 +1,10 @@
 //
-// 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.
 //
 
 // Context.cpp: Implements the gl::Context class, managing all GL state and performing
 // rendering operations. It is the GLES2 specific implementation of EGLContext.
 
 #include "libGLESv2/Context.h"
@@ -20,27 +20,33 @@
 #include "libGLESv2/ResourceManager.h"
 #include "libGLESv2/Buffer.h"
 #include "libGLESv2/Fence.h"
 #include "libGLESv2/FrameBuffer.h"
 #include "libGLESv2/Program.h"
 #include "libGLESv2/RenderBuffer.h"
 #include "libGLESv2/Shader.h"
 #include "libGLESv2/Texture.h"
-#include "libGLESv2/geometry/VertexDataManager.h"
-#include "libGLESv2/geometry/IndexDataManager.h"
+#include "libGLESv2/VertexDataManager.h"
+#include "libGLESv2/IndexDataManager.h"
 
 #undef near
 #undef far
 
+namespace
+{
+    enum { CLOSING_INDEX_BUFFER_SIZE = 4096 };
+}
+
 namespace gl
 {
-Context::Context(const egl::Config *config, const gl::Context *shareContext)
-    : mConfig(config)
+Context::Context(const egl::Config *config, const gl::Context *shareContext) : mConfig(config)
 {
+    mFenceHandleAllocator.setBaseHandle(0);
+
     setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
 
     mState.depthClearValue = 1.0f;
     mState.stencilClearValue = 0;
 
     mState.cullFace = false;
     mState.cullMode = GL_BACK;
     mState.frontFace = GL_CCW;
@@ -135,16 +141,17 @@ Context::Context(const egl::Config *conf
     mState.currentProgram = 0;
 
     mState.packAlignment = 4;
     mState.unpackAlignment = 4;
 
     mVertexDataManager = NULL;
     mIndexDataManager = NULL;
     mBlit = NULL;
+    mClosingIB = NULL;
 
     mInvalidEnum = false;
     mInvalidValue = false;
     mInvalidOperation = false;
     mOutOfMemory = false;
     mInvalidFramebufferOperation = false;
 
     mHasBeenCurrent = false;
@@ -179,25 +186,25 @@ Context::~Context()
     }
 
     while (!mMultiSampleSupport.empty())
     {
         delete [] mMultiSampleSupport.begin()->second;
         mMultiSampleSupport.erase(mMultiSampleSupport.begin());
     }
 
-    for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
+    for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
     {
-        for (int sampler = 0; sampler < MAX_TEXTURE_IMAGE_UNITS; sampler++)
+        for (int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF; sampler++)
         {
             mState.samplerTexture[type][sampler].set(NULL);
         }
     }
 
-    for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
+    for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
     {
         mIncompleteTextures[type].set(NULL);
     }
 
     for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
     {
         mState.vertexAttribute[i].mBoundBuffer.set(NULL);
     }
@@ -207,16 +214,17 @@ Context::~Context()
     mState.renderbuffer.set(NULL);
 
     mTexture2DZero.set(NULL);
     mTextureCubeMapZero.set(NULL);
 
     delete mVertexDataManager;
     delete mIndexDataManager;
     delete mBlit;
+    delete mClosingIB;
 
     if (mMaskedClearSavedState)
     {
         mMaskedClearSavedState->Release();
     }
 
     mResourceManager->release();
 }
@@ -229,16 +237,17 @@ void Context::makeCurrent(egl::Display *
     {
         mDeviceCaps = display->getDeviceCaps();
 
         mVertexDataManager = new VertexDataManager(this, device);
         mIndexDataManager = new IndexDataManager(this, device);
         mBlit = new Blit(this);
 
         mSupportsShaderModel3 = mDeviceCaps.PixelShaderVersion == D3DPS_VERSION(3, 0);
+        mSupportsVertexTexture = display->getVertexTextureSupport();
 
         mMaxTextureDimension = std::min(std::min((int)mDeviceCaps.MaxTextureWidth, (int)mDeviceCaps.MaxTextureHeight),
                                         (int)gl::IMPLEMENTATION_MAX_TEXTURE_SIZE);
         mMaxCubeTextureDimension = std::min(mMaxTextureDimension, (int)gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE);
         mMaxRenderbufferDimension = mMaxTextureDimension;
         mMaxTextureLevel = log2(mMaxTextureDimension) + 1;
         TRACE("MaxTextureDimension=%d, MaxCubeTextureDimension=%d, MaxRenderbufferDimension=%d, MaxTextureLevel=%d",
               mMaxTextureDimension, mMaxCubeTextureDimension, mMaxRenderbufferDimension, mMaxTextureLevel);
@@ -314,21 +323,31 @@ void Context::makeCurrent(egl::Display *
     }
     
     markAllStateDirty();
 }
 
 // This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.
 void Context::markAllStateDirty()
 {
+    for (int t = 0; t < MAX_TEXTURE_IMAGE_UNITS; t++)
+    {
+        mAppliedTextureSerialPS[t] = 0;
+    }
+
+    for (int t = 0; t < MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF; t++)
+    {
+        mAppliedTextureSerialVS[t] = 0;
+    }
+
+    mAppliedProgramSerial = 0;
     mAppliedRenderTargetSerial = 0;
     mAppliedDepthbufferSerial = 0;
     mAppliedStencilbufferSerial = 0;
     mDepthStencilInitialized = false;
-    mAppliedProgram = 0;
 
     mClearStateDirty = true;
     mCullStateDirty = true;
     mDepthStateDirty = true;
     mMaskStateDirty = true;
     mBlendStateDirty = true;
     mStencilStateDirty = true;
     mPolygonOffsetStateDirty = true;
@@ -705,17 +724,17 @@ void Context::setDepthMask(bool mask)
 {
     if (mState.depthMask != mask)
     {
         mState.depthMask = mask;
         mMaskStateDirty = true;
     }
 }
 
-void Context::setActiveSampler(int active)
+void Context::setActiveSampler(unsigned int active)
 {
     mState.activeSampler = active;
 }
 
 GLuint Context::getReadFramebufferHandle() const
 {
     return mState.readFramebuffer;
 }
@@ -809,36 +828,26 @@ GLuint Context::createTexture()
 GLuint Context::createRenderbuffer()
 {
     return mResourceManager->createRenderbuffer();
 }
 
 // Returns an unused framebuffer name
 GLuint Context::createFramebuffer()
 {
-    unsigned int handle = 1;
-
-    while (mFramebufferMap.find(handle) != mFramebufferMap.end())
-    {
-        handle++;
-    }
+    GLuint handle = mFramebufferHandleAllocator.allocate();
 
     mFramebufferMap[handle] = NULL;
 
     return handle;
 }
 
 GLuint Context::createFence()
 {
-    unsigned int handle = 0;
-
-    while (mFenceMap.find(handle) != mFenceMap.end())
-    {
-        handle++;
-    }
+    GLuint handle = mFenceHandleAllocator.allocate();
 
     mFenceMap[handle] = new Fence;
 
     return handle;
 }
 
 void Context::deleteBuffer(GLuint buffer)
 {
@@ -883,27 +892,29 @@ void Context::deleteRenderbuffer(GLuint 
 void Context::deleteFramebuffer(GLuint framebuffer)
 {
     FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer);
 
     if (framebufferObject != mFramebufferMap.end())
     {
         detachFramebuffer(framebuffer);
 
+        mFramebufferHandleAllocator.release(framebufferObject->first);
         delete framebufferObject->second;
         mFramebufferMap.erase(framebufferObject);
     }
 }
 
 void Context::deleteFence(GLuint fence)
 {
     FenceMap::iterator fenceObject = mFenceMap.find(fence);
 
     if (fenceObject != mFenceMap.end())
     {
+        mFenceHandleAllocator.release(fenceObject->first);
         delete fenceObject->second;
         mFenceMap.erase(fenceObject);
     }
 }
 
 Buffer *Context::getBuffer(GLuint handle)
 {
     return mResourceManager->getBuffer(handle);
@@ -950,26 +961,26 @@ void Context::bindElementArrayBuffer(uns
 {
     mResourceManager->checkBufferAllocation(buffer);
 
     mState.elementArrayBuffer.set(getBuffer(buffer));
 }
 
 void Context::bindTexture2D(GLuint texture)
 {
-    mResourceManager->checkTextureAllocation(texture, SAMPLER_2D);
-
-    mState.samplerTexture[SAMPLER_2D][mState.activeSampler].set(getTexture(texture));
+    mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
+
+    mState.samplerTexture[TEXTURE_2D][mState.activeSampler].set(getTexture(texture));
 }
 
 void Context::bindTextureCubeMap(GLuint texture)
 {
-    mResourceManager->checkTextureAllocation(texture, SAMPLER_CUBE);
-
-    mState.samplerTexture[SAMPLER_CUBE][mState.activeSampler].set(getTexture(texture));
+    mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);
+
+    mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].set(getTexture(texture));
 }
 
 void Context::bindReadFramebuffer(GLuint framebuffer)
 {
     if (!getFramebuffer(framebuffer))
     {
         mFramebufferMap[framebuffer] = new Framebuffer();
     }
@@ -1068,35 +1079,35 @@ Buffer *Context::getElementArrayBuffer()
 
 Program *Context::getCurrentProgram()
 {
     return mResourceManager->getProgram(mState.currentProgram);
 }
 
 Texture2D *Context::getTexture2D()
 {
-    return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, SAMPLER_2D));
+    return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
 }
 
 TextureCubeMap *Context::getTextureCubeMap()
 {
-    return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, SAMPLER_CUBE));
+    return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
 }
 
-Texture *Context::getSamplerTexture(unsigned int sampler, SamplerType type)
+Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type)
 {
     GLuint texid = mState.samplerTexture[type][sampler].id();
 
     if (texid == 0)   // Special case: 0 refers to different initial textures based on the target
     {
         switch (type)
         {
           default: UNREACHABLE();
-          case SAMPLER_2D: return mTexture2DZero.get();
-          case SAMPLER_CUBE: return mTextureCubeMapZero.get();
+          case TEXTURE_2D: return mTexture2DZero.get();
+          case TEXTURE_CUBE: return mTextureCubeMapZero.get();
         }
     }
 
     return mState.samplerTexture[type][sampler].get();
 }
 
 bool Context::getBooleanv(GLenum pname, GLboolean *params)
 {
@@ -1178,18 +1189,18 @@ bool Context::getIntegerv(GLenum pname, 
     // GetIntegerv as its native query function. As it would require conversion in any
     // case, this should make no difference to the calling application. You may find it in 
     // Context::getFloatv.
     switch (pname)
     {
       case GL_MAX_VERTEX_ATTRIBS:               *params = gl::MAX_VERTEX_ATTRIBS;               break;
       case GL_MAX_VERTEX_UNIFORM_VECTORS:       *params = gl::MAX_VERTEX_UNIFORM_VECTORS;       break;
       case GL_MAX_VARYING_VECTORS:              *params = getMaximumVaryingVectors();           break;
-      case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = gl::MAX_COMBINED_TEXTURE_IMAGE_UNITS; break;
-      case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = gl::MAX_VERTEX_TEXTURE_IMAGE_UNITS;   break;
+      case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = getMaximumCombinedTextureImageUnits(); break;
+      case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = getMaximumVertexTextureImageUnits();  break;
       case GL_MAX_TEXTURE_IMAGE_UNITS:          *params = gl::MAX_TEXTURE_IMAGE_UNITS;          break;
       case GL_MAX_FRAGMENT_UNIFORM_VECTORS:     *params = getMaximumFragmentUniformVectors();   break;
       case GL_MAX_RENDERBUFFER_SIZE:            *params = getMaximumRenderbufferDimension();    break;
       case GL_NUM_SHADER_BINARY_FORMATS:        *params = 0;                                    break;
       case GL_SHADER_BINARY_FORMATS:      /* no shader binary formats are supported */          break;
       case GL_ARRAY_BUFFER_BINDING:             *params = mState.arrayBuffer.id();              break;
       case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = mState.elementArrayBuffer.id();       break;
       //case GL_FRAMEBUFFER_BINDING:            // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
@@ -1367,34 +1378,34 @@ bool Context::getIntegerv(GLenum pname, 
             else
             {
                 *params = 0;
             }
         }
         break;
       case GL_TEXTURE_BINDING_2D:
         {
-            if (mState.activeSampler < 0 || mState.activeSampler > gl::MAX_TEXTURE_IMAGE_UNITS - 1)
+            if (mState.activeSampler < 0 || mState.activeSampler > getMaximumCombinedTextureImageUnits() - 1)
             {
                 error(GL_INVALID_OPERATION);
                 return false;
             }
 
-            *params = mState.samplerTexture[SAMPLER_2D][mState.activeSampler].id();
+            *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].id();
         }
         break;
       case GL_TEXTURE_BINDING_CUBE_MAP:
         {
-            if (mState.activeSampler < 0 || mState.activeSampler > gl::MAX_TEXTURE_IMAGE_UNITS - 1)
+            if (mState.activeSampler < 0 || mState.activeSampler > getMaximumCombinedTextureImageUnits() - 1)
             {
                 error(GL_INVALID_OPERATION);
                 return false;
             }
 
-            *params = mState.samplerTexture[SAMPLER_CUBE][mState.activeSampler].id();
+            *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].id();
         }
         break;
       default:
         return false;
     }
 
     return true;
 }
@@ -1567,19 +1578,17 @@ bool Context::getQueryParameterInfo(GLen
 bool Context::applyRenderTarget(bool ignoreViewport)
 {
     IDirect3DDevice9 *device = getDevice();
 
     Framebuffer *framebufferObject = getDrawFramebuffer();
 
     if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
     {
-        error(GL_INVALID_FRAMEBUFFER_OPERATION);
-
-        return false;
+        return error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
     }
 
     IDirect3DSurface9 *renderTarget = framebufferObject->getRenderTarget();
 
     if (!renderTarget)
     {
         return false;   // Context must be lost
     }
@@ -1738,17 +1747,17 @@ void Context::applyState(GLenum drawMode
             device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
         }
 
         mCullStateDirty = false;
     }
 
     if (mDepthStateDirty)
     {
-        if (mState.depthTest && framebufferObject->getDepthbufferType() != GL_NONE)
+        if (mState.depthTest)
         {
             device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
             device->SetRenderState(D3DRS_ZFUNC, es2dx::ConvertComparison(mState.depthFunc));
         }
         else
         {
             device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
         }
@@ -1783,17 +1792,16 @@ void Context::applyState(GLenum drawMode
                 mState.destBlendRGB != mState.destBlendAlpha || 
                 mState.blendEquationRGB != mState.blendEquationAlpha)
             {
                 device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
 
                 device->SetRenderState(D3DRS_SRCBLENDALPHA, es2dx::ConvertBlendFunc(mState.sourceBlendAlpha));
                 device->SetRenderState(D3DRS_DESTBLENDALPHA, es2dx::ConvertBlendFunc(mState.destBlendAlpha));
                 device->SetRenderState(D3DRS_BLENDOPALPHA, es2dx::ConvertBlendOp(mState.blendEquationAlpha));
-
             }
             else
             {
                 device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE);
             }
         }
         else
         {
@@ -1946,43 +1954,27 @@ void Context::applyState(GLenum drawMode
         device->SetRenderState(D3DRS_DITHERENABLE, mState.dither ? TRUE : FALSE);
 
         mDitherStateDirty = false;
     }
 
     mFrontFaceDirty = false;
 }
 
-// Fill in the semanticIndex field of the array of TranslatedAttributes based on the active GLSL program.
-void Context::lookupAttributeMapping(TranslatedAttribute *attributes)
-{
-    for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
-    {
-        if (attributes[i].active)
-        {
-            attributes[i].semanticIndex = getCurrentProgram()->getSemanticIndex(i);
-        }
-    }
-}
-
 GLenum Context::applyVertexBuffer(GLint first, GLsizei count)
 {
-    TranslatedAttribute translated[MAX_VERTEX_ATTRIBS];
-
-    GLenum err = mVertexDataManager->prepareVertexData(first, count, translated);
+    TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];
+
+    GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes);
     if (err != GL_NO_ERROR)
     {
         return err;
     }
 
-    lookupAttributeMapping(translated);
-
-    mVertexDataManager->setupAttributes(translated);
-
-    return GL_NO_ERROR;
+    return mVertexDeclarationCache.applyDeclaration(attributes, getCurrentProgram());
 }
 
 // Applies the indices and element array bindings to the Direct3D 9 device
 GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
 {
     IDirect3DDevice9 *device = getDevice();
     GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer.get(), indices, indexInfo);
 
@@ -2000,77 +1992,103 @@ void Context::applyShaders()
     IDirect3DDevice9 *device = getDevice();
     Program *programObject = getCurrentProgram();
     IDirect3DVertexShader9 *vertexShader = programObject->getVertexShader();
     IDirect3DPixelShader9 *pixelShader = programObject->getPixelShader();
 
     device->SetVertexShader(vertexShader);
     device->SetPixelShader(pixelShader);
 
-    if (programObject->getSerial() != mAppliedProgram)
+    if (programObject->getSerial() != mAppliedProgramSerial)
     {
         programObject->dirtyAllUniforms();
-        programObject->dirtyAllSamplers();
-        mAppliedProgram = programObject->getSerial();
+        mAppliedProgramSerial = programObject->getSerial();
     }
 
     programObject->applyUniforms();
 }
 
 // Applies the textures and sampler states to the Direct3D 9 device
 void Context::applyTextures()
 {
+    applyTextures(SAMPLER_PIXEL);
+
+    if (mSupportsVertexTexture)
+    {
+        applyTextures(SAMPLER_VERTEX);
+    }
+}
+
+// For each Direct3D 9 sampler of either the pixel or vertex stage,
+// looks up the corresponding OpenGL texture image unit and texture type,
+// and sets the texture and its addressing/filtering state (or NULL when inactive).
+void Context::applyTextures(SamplerType type)
+{
     IDirect3DDevice9 *device = getDevice();
     Program *programObject = getCurrentProgram();
 
-    for (int sampler = 0; sampler < MAX_TEXTURE_IMAGE_UNITS; sampler++)
+    int samplerCount = (type == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF;   // Range of Direct3D 9 samplers of given sampler type
+
+    for (int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++)
     {
-        int textureUnit = programObject->getSamplerMapping(sampler);
+        int textureUnit = programObject->getSamplerMapping(type, samplerIndex);   // OpenGL texture image unit index
+        int d3dSampler = (type == SAMPLER_PIXEL) ? samplerIndex : D3DVERTEXTEXTURESAMPLER0 + samplerIndex;
+        unsigned int *appliedTextureSerial = (type == SAMPLER_PIXEL) ? mAppliedTextureSerialPS : mAppliedTextureSerialVS;
+
         if (textureUnit != -1)
         {
-            SamplerType textureType = programObject->getSamplerType(sampler);
+            TextureType textureType = programObject->getSamplerTextureType(type, samplerIndex);
 
             Texture *texture = getSamplerTexture(textureUnit, textureType);
 
-            if (programObject->isSamplerDirty(sampler) || texture->isDirty())
+            if (appliedTextureSerial[samplerIndex] != texture->getSerial() || texture->isDirtyParameter() || texture->isDirtyImage())
             {
-                if (texture->isComplete())
+                IDirect3DBaseTexture9 *d3dTexture = texture->getTexture();
+
+                if (d3dTexture)
                 {
-                    GLenum wrapS = texture->getWrapS();
-                    GLenum wrapT = texture->getWrapT();
-                    GLenum minFilter = texture->getMinFilter();
-                    GLenum magFilter = texture->getMagFilter();
-
-                    device->SetSamplerState(sampler, D3DSAMP_ADDRESSU, es2dx::ConvertTextureWrap(wrapS));
-                    device->SetSamplerState(sampler, D3DSAMP_ADDRESSV, es2dx::ConvertTextureWrap(wrapT));
-
-                    device->SetSamplerState(sampler, D3DSAMP_MAGFILTER, es2dx::ConvertMagFilter(magFilter));
-                    D3DTEXTUREFILTERTYPE d3dMinFilter, d3dMipFilter;
-                    es2dx::ConvertMinFilter(minFilter, &d3dMinFilter, &d3dMipFilter);
-                    device->SetSamplerState(sampler, D3DSAMP_MINFILTER, d3dMinFilter);
-                    device->SetSamplerState(sampler, D3DSAMP_MIPFILTER, d3dMipFilter);
-
-                    device->SetTexture(sampler, texture->getTexture());
+                    if (appliedTextureSerial[samplerIndex] != texture->getSerial() || texture->isDirtyParameter())
+                    {
+                        GLenum wrapS = texture->getWrapS();
+                        GLenum wrapT = texture->getWrapT();
+                        GLenum minFilter = texture->getMinFilter();
+                        GLenum magFilter = texture->getMagFilter();
+
+                        device->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU, es2dx::ConvertTextureWrap(wrapS));
+                        device->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, es2dx::ConvertTextureWrap(wrapT));
+
+                        device->SetSamplerState(d3dSampler, D3DSAMP_MAGFILTER, es2dx::ConvertMagFilter(magFilter));
+                        D3DTEXTUREFILTERTYPE d3dMinFilter, d3dMipFilter;
+                        es2dx::ConvertMinFilter(minFilter, &d3dMinFilter, &d3dMipFilter);
+                        device->SetSamplerState(d3dSampler, D3DSAMP_MINFILTER, d3dMinFilter);
+                        device->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter);
+                    }
+
+                    if (appliedTextureSerial[samplerIndex] != texture->getSerial() || texture->isDirtyImage())
+                    {
+                        device->SetTexture(d3dSampler, d3dTexture);
+                    }
                 }
                 else
                 {
-                    device->SetTexture(sampler, getIncompleteTexture(textureType)->getTexture());
+                    device->SetTexture(d3dSampler, getIncompleteTexture(textureType)->getTexture());
                 }
+
+                appliedTextureSerial[samplerIndex] = texture->getSerial();
+                texture->resetDirty();
             }
-
-            programObject->setSamplerDirty(sampler, false);
         }
         else
         {
-            if (programObject->isSamplerDirty(sampler))
+            if (appliedTextureSerial[samplerIndex] != 0)
             {
-                device->SetTexture(sampler, NULL);
-                programObject->setSamplerDirty(sampler, false);
+                device->SetTexture(d3dSampler, NULL);
+                appliedTextureSerial[samplerIndex] = 0;
             }
-        }   
+        }
     }
 }
 
 void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels)
 {
     Framebuffer *framebuffer = getReadFramebuffer();
 
     if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
@@ -2113,22 +2131,22 @@ void Context::readPixels(GLint x, GLint 
     result = device->GetRenderTargetData(renderTarget, systemSurface);
 
     if (FAILED(result))
     {
         systemSurface->Release();
 
         switch (result)
         {
-            case D3DERR_DRIVERINTERNALERROR:
-            case D3DERR_DEVICELOST:
-                return error(GL_OUT_OF_MEMORY);
-            default:
-                UNREACHABLE();
-                return;   // No sensible error to generate
+          case D3DERR_DRIVERINTERNALERROR:
+          case D3DERR_DEVICELOST:
+            return error(GL_OUT_OF_MEMORY);
+          default:
+            UNREACHABLE();
+            return;   // No sensible error to generate
         }
     }
 
     D3DLOCKED_RECT lock;
     RECT rect = transformPixelRect(x, y, width, height, desc.Height);
     rect.left = clamp(rect.left, 0L, static_cast<LONG>(desc.Width));
     rect.top = clamp(rect.top, 0L, static_cast<LONG>(desc.Height));
     rect.right = clamp(rect.right, 0L, static_cast<LONG>(desc.Width));
@@ -2328,19 +2346,17 @@ void Context::readPixels(GLint x, GLint 
 }
 
 void Context::clear(GLbitfield mask)
 {
     Framebuffer *framebufferObject = getDrawFramebuffer();
 
     if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
     {
-        error(GL_INVALID_FRAMEBUFFER_OPERATION);
-
-        return;
+        return error(GL_INVALID_FRAMEBUFFER_OPERATION);
     }
 
     egl::Display *display = getDisplay();
     IDire