Merge inbound to m-c. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Fri, 06 Feb 2015 09:06:38 -0500
changeset 244218 17ad80d798243aceababa9976efea3b7ed0d1262
parent 244209 03b0004eba32320e5e7cca1ff9621a90c4489381 (current diff)
parent 244188 9c95e28087ca0f3c355e0ebab92d11b1be9fba10 (diff)
child 244237 e0f56d3f1fc03cc60fa37b405f2bb5d1440d5a47
push idunknown
push userunknown
push dateunknown
reviewersmerge
milestone38.0a1
Merge inbound to m-c. a=merge
gfx/angle/src/build_angle.gyp
testing/web-platform/meta/encoding/api-replacement-encodings.html.ini
testing/web-platform/meta/encoding/textdecoder-fatal-streaming.html.ini
testing/web-platform/meta/encoding/textdecoder-fatal.html.ini
testing/web-platform/meta/encoding/textdecoder-utf16-surrogates.html.ini
testing/web-platform/meta/encoding/textencoder-constructor-non-utf.html.ini
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1182,25 +1182,25 @@ pref("browser.tabs.remote.desktopbehavio
 
 #if defined(XP_WIN) && defined(MOZ_SANDBOX)
 // When this pref is true the Windows process sandbox will set up dummy
 // interceptions and log to the browser console when calls fail in the sandboxed
 // process and also if they are subsequently allowed by the broker process.
 // This will require a restart.
 pref("security.sandbox.windows.log", false);
 
-// Controls whether the Windows NPAPI plugin process is sandboxed by default.
+// Controls whether and how the Windows NPAPI plugin process is sandboxed.
 // To get a different setting for a particular plugin replace "default", with
 // the plugin's nice file name, see: nsPluginTag::GetNiceFileName.
-pref("dom.ipc.plugins.sandbox.default", false);
-pref("dom.ipc.plugins.sandbox.flash", true);
-
-// This controls whether the Windows NPAPI process sandbox is using a more
-// strict sandboxing policy.  This will require a restart.
-pref("dom.ipc.plugins.moreStrictSandbox", false);
+// On windows these levels are:
+// 0 - no sandbox
+// 1 - sandbox with USER_NON_ADMIN access token level
+// 2 - a more strict sandbox, which might cause functionality issues
+pref("dom.ipc.plugins.sandbox-level.default", 0);
+pref("dom.ipc.plugins.sandbox-level.flash", 1);
 
 #if defined(MOZ_CONTENT_SANDBOX)
 // This controls whether the Windows content process sandbox is using a more
 // strict sandboxing policy.  This will require a restart.
 pref("security.sandbox.windows.content.moreStrict", false);
 
 #if defined(MOZ_STACKWALKING)
 // This controls the depth of stack trace that is logged when Windows sandbox
--- a/dom/apps/AppsUtils.jsm
+++ b/dom/apps/AppsUtils.jsm
@@ -668,20 +668,27 @@ this.AppsUtils = {
   // of the file to be read.
   loadJSONAsync: function(aPath) {
     let deferred = Promise.defer();
 
     try {
       let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
       file.initWithPath(aPath);
 
-      let channel = NetUtil.newChannel(file);
+      let channel = NetUtil.newChannel2(file,
+                                        null,
+                                        null,
+                                        null,      // aLoadingNode
+                                        Services.scriptSecurityManager.getSystemPrincipal(),
+                                        null,      // aTriggeringPrincipal
+                                        Ci.nsILoadInfo.SEC_NORMAL,
+                                        Ci.nsIContentPolicy.TYPE_OTHER);
       channel.contentType = "application/json";
 
-      NetUtil.asyncFetch(channel, function(aStream, aResult) {
+      NetUtil.asyncFetch2(channel, function(aStream, aResult) {
         if (!Components.isSuccessCode(aResult)) {
           deferred.resolve(null);
 
           if (aResult == Cr.NS_ERROR_FILE_NOT_FOUND) {
             // We expect this under certain circumstances, like for webapps.json
             // on firstrun, so we return early without reporting an error.
             return;
           }
--- a/dom/apps/OfflineCacheInstaller.jsm
+++ b/dom/apps/OfflineCacheInstaller.jsm
@@ -32,23 +32,21 @@ const applicationCacheService =
     .getService(Ci.nsIApplicationCacheService);
 
 
 function debug(aMsg) {
   //dump("-*-*- OfflineCacheInstaller.jsm : " + aMsg + "\n");
 }
 
 
-function enableOfflineCacheForApp(origin, appId) {
-  let principal = Services.scriptSecurityManager.getAppCodebasePrincipal(
-                    origin, appId, false);
-  Services.perms.addFromPrincipal(principal, 'offline-app',
+function enableOfflineCacheForApp(aPrincipal) {
+  Services.perms.addFromPrincipal(aPrincipal, 'offline-app',
                                   Ci.nsIPermissionManager.ALLOW_ACTION);
   // Prevent cache from being evicted:
-  Services.perms.addFromPrincipal(principal, 'pin-app',
+  Services.perms.addFromPrincipal(aPrincipal, 'pin-app',
                                   Ci.nsIPermissionManager.ALLOW_ACTION);
 }
 
 
 function storeCache(applicationCache, url, file, itemType) {
   let storage =
     Services.cache2.appCacheStorage(LoadContextInfo.default, applicationCache);
   let uri = Services.io.newURI(url, null, null);
@@ -75,20 +73,28 @@ function storeCache(applicationCache, ur
         cacheEntry.markValid();
         debug (file.path + ' -> ' + url + ' (' + itemType + ')');
         applicationCache.markEntry(url, itemType);
         cacheEntry.close();
       }
   });
 }
 
-function readFile(aFile, aCallback) {
-  let channel = NetUtil.newChannel(aFile);
+function readFile(aFile, aPrincipal, aCallback) {
+
+  let channel = NetUtil.newChannel2(aFile,
+                                    null,
+                                    null,
+                                    null,      // aLoadingNode
+                                    aPrincipal,
+                                    null,      // aTriggeringPrincipal
+                                    Ci.nsILoadInfo.SEC_NORMAL,
+                                    Ci.nsIContentPolicy.TYPE_OTHER);
   channel.contentType = "plain/text";
-  NetUtil.asyncFetch(channel, function(aStream, aResult) {
+  NetUtil.asyncFetch2(channel, function(aStream, aResult) {
     if (!Components.isSuccessCode(aResult)) {
       Cu.reportError("OfflineCacheInstaller: Could not read file " + aFile.path);
       if (aCallback)
         aCallback(null);
       return;
     }
 
     // Obtain a converter to read from a UTF-8 encoded input stream.
@@ -206,29 +212,32 @@ function installCache(app) {
   if (!cacheDir.exists())
     return;
 
   let cacheManifest = cacheDir.clone();
   cacheManifest.append('manifest.appcache');
   if (!cacheManifest.exists())
     return;
 
-  enableOfflineCacheForApp(app.origin, app.localId);
+  let principal = Services.scriptSecurityManager.getAppCodebasePrincipal(
+                    app.origin, app.localId, false);
+
+  enableOfflineCacheForApp(principal);
 
   // Get the url for the manifest.
   let appcacheURL = app.appcache_path;
 
   // The group ID contains application id and 'f' for not being hosted in
   // a browser element, but a mozbrowser iframe.
   // See netwerk/cache/nsDiskCacheDeviceSQL.cpp: AppendJARIdentifier
   let groupID = appcacheURL + '#' + app.localId+ '+f';
   let applicationCache = applicationCacheService.createApplicationCache(groupID);
   applicationCache.activate();
 
-  readFile(cacheManifest, function readAppCache(content) {
+  readFile(cacheManifest, principal, function readAppCache(content) {
     let entries = parseAppCache(app, cacheManifest.path, content);
 
     entries.urls.forEach(function processCachedFile(url) {
       // Get this nsIFile from cache folder for this URL
       // We have absolute urls, so remove the origin part to locate the
       // files.
       let path = url.replace(app.origin.spec, '');
       let file = cacheDir.clone();
--- a/dom/apps/TrustedHostedAppsUtils.jsm
+++ b/dom/apps/TrustedHostedAppsUtils.jsm
@@ -195,17 +195,27 @@ this.TrustedHostedAppsUtils = {
       certDb = Cc["@mozilla.org/security/x509certdb;1"]
                  .getService(Ci.nsIX509CertDB);
     } catch (e) {
       debug("nsIX509CertDB error: " + e);
       // unrecoverable error, don't bug the user
       throw "CERTDB_ERROR";
     }
 
-    let mRequestChannel = NetUtil.newChannel(aApp.manifestURL)
+    let principal = Services.scriptSecurityManager.getAppCodebasePrincipal(
+                      aApp.origin, aApp.localId, false);
+
+    let mRequestChannel = NetUtil.newChannel2(aApp.manifestURL,
+                                              null,
+                                              null,
+                                              null,      // aLoadingNode
+                                              principal,
+                                              null,      // aTriggeringPrincipal
+                                              Ci.nsILoadInfo.SEC_NORMAL,
+                                              Ci.nsIContentPolicy.TYPE_OTHER)
                                  .QueryInterface(Ci.nsIHttpChannel);
     mRequestChannel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
     mRequestChannel.notificationCallbacks =
       AppsUtils.createLoadContext(aAppId, false);
 
     // The manifest signature must be located at the same path as the
     // manifest and have the same file name, only the file extension
     // should differ. Any fragment or query parameter will be ignored.
@@ -217,39 +227,46 @@ this.TrustedHostedAppsUtils = {
         .QueryInterface(Ci.nsIURL);
       signatureURL = mURL.prePath +
         mURL.directory + mURL.fileBaseName + signatureFileExtension;
     } catch(e) {
       deferred.reject("SIGNATURE_PATH_INVALID");
       return;
     }
 
-    let sRequestChannel = NetUtil.newChannel(signatureURL)
+    let sRequestChannel = NetUtil.newChannel2(signatureURL,
+                                              null,
+                                              null,
+                                              null,      // aLoadingNode
+                                              principal,
+                                              null,      // aTriggeringPrincipal
+                                              Ci.nsILoadInfo.SEC_NORMAL,
+                                              Ci.nsIContentPolicy.TYPE_OTHER)
       .QueryInterface(Ci.nsIHttpChannel);
     sRequestChannel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
     sRequestChannel.notificationCallbacks =
       AppsUtils.createLoadContext(aAppId, false);
     let getAsyncFetchCallback = (resolve, reject) =>
         (aInputStream, aResult) => {
           if (!Components.isSuccessCode(aResult)) {
             debug("Failed to download file");
             reject("MANIFEST_FILE_UNAVAILABLE");
             return;
           }
           resolve(aInputStream);
         };
 
     Promise.all([
       new Promise((resolve, reject) => {
-        NetUtil.asyncFetch(mRequestChannel,
-                           getAsyncFetchCallback(resolve, reject));
+        NetUtil.asyncFetch2(mRequestChannel,
+                            getAsyncFetchCallback(resolve, reject));
       }),
       new Promise((resolve, reject) => {
-        NetUtil.asyncFetch(sRequestChannel,
-                           getAsyncFetchCallback(resolve, reject));
+        NetUtil.asyncFetch2(sRequestChannel,
+                            getAsyncFetchCallback(resolve, reject));
       })
     ]).then(([aManifestStream, aSignatureStream]) => {
       this._verifySignedFile(aManifestStream, aSignatureStream, certDb)
         .then(deferred.resolve, deferred.reject);
     }, deferred.reject);
 
     return deferred.promise;
   },
--- a/dom/apps/Webapps.jsm
+++ b/dom/apps/Webapps.jsm
@@ -3424,21 +3424,39 @@ this.DOMApplicationRegistry = {
     }
     return true;
   },
 
   _getRequestChannel: function(aFullPackagePath, aIsLocalFileInstall, aOldApp,
                                aNewApp) {
     let requestChannel;
 
+    let appURI = NetUtil.newURI(aNewApp.origin, null, null);
+    let principal = Services.scriptSecurityManager.getAppCodebasePrincipal(
+                      appURI, aNewApp.localId, false);
+
     if (aIsLocalFileInstall) {
-      requestChannel = NetUtil.newChannel(aFullPackagePath)
+      requestChannel = NetUtil.newChannel2(aFullPackagePath,
+                                           null,
+                                           null,
+                                           null,      // aLoadingNode
+                                           principal,
+                                           null,      // aTriggeringPrincipal
+                                           Ci.nsILoadInfo.SEC_NORMAL,
+                                           Ci.nsIContentPolicy.TYPE_OTHER)
                               .QueryInterface(Ci.nsIFileChannel);
     } else {
-      requestChannel = NetUtil.newChannel(aFullPackagePath)
+      requestChannel = NetUtil.newChannel2(aFullPackagePath,
+                                           null,
+                                           null,
+                                           null,      // aLoadingNode
+                                           principal,
+                                           null,      // aTriggeringPrincipal
+                                           Ci.nsILoadInfo.SEC_NORMAL,
+                                           Ci.nsIContentPolicy.TYPE_OTHER)
                               .QueryInterface(Ci.nsIHttpChannel);
       requestChannel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
     }
 
     if (aOldApp.packageEtag && !aIsLocalFileInstall) {
       debug("Add If-None-Match header: " + aOldApp.packageEtag);
       requestChannel.setRequestHeader("If-None-Match", aOldApp.packageEtag,
                                       false);
@@ -3524,17 +3542,17 @@ this.DOMApplicationRegistry = {
    * @returns {String} the MD5 hash of the file
    */
   _computeFileHash: function(aFilePath) {
     let deferred = Promise.defer();
 
     let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
     file.initWithPath(aFilePath);
 
-    NetUtil.asyncFetch(file, function(inputStream, status) {
+    NetUtil.asyncFetch2(file, function(inputStream, status) {
       if (!Components.isSuccessCode(status)) {
         debug("Error reading " + aFilePath + ": " + e);
         deferred.reject();
         return;
       }
 
       let hasher = Cc["@mozilla.org/security/hash;1"]
                      .createInstance(Ci.nsICryptoHash);
@@ -3551,17 +3569,22 @@ this.DOMApplicationRegistry = {
 
       // We're passing false to get the binary hash and not base64.
       let data = hasher.finish(false);
       // Convert the binary hash data to a hex string.
       let hash = [toHexString(data.charCodeAt(i)) for (i in data)].join("");
       debug("File hash computed: " + hash);
 
       deferred.resolve(hash);
-    });
+    },
+    null,      // aLoadingNode
+    Services.scriptSecurityManager.getSystemPrincipal(),
+    null,      // aTriggeringPrincipal
+    Ci.nsILoadInfo.SEC_NORMAL,
+    Ci.nsIContentPolicy.TYPE_OTHER);
 
     return deferred.promise;
   },
 
   /**
    * Send an "applied" event right away for the package being installed.
    *
    * XXX We use this to exit the app update process early when the downloaded
--- a/dom/archivereader/ArchiveReader.cpp
+++ b/dom/archivereader/ArchiveReader.cpp
@@ -32,17 +32,17 @@ ArchiveReader::Constructor(const GlobalO
   if (!window) {
     aError.Throw(NS_ERROR_UNEXPECTED);
     return nullptr;
   }
 
   nsAutoCString encoding;
   if (!EncodingUtils::FindEncodingForLabelNoReplacement(aOptions.mEncoding,
                                                         encoding)) {
-    aError.ThrowTypeError(MSG_ENCODING_NOT_SUPPORTED, &aOptions.mEncoding);
+    aError.ThrowRangeError(MSG_ENCODING_NOT_SUPPORTED, &aOptions.mEncoding);
     return nullptr;
   }
 
   nsRefPtr<ArchiveReader> reader =
     new ArchiveReader(aBlob, window, encoding);
   return reader.forget();
 }
 
--- a/dom/archivereader/test/test_nonUnicode.html
+++ b/dom/archivereader/test/test_nonUnicode.html
@@ -58,17 +58,17 @@
   function test2()
   {
     var binaryFile = createNonUnicodeData();
 
     try {
       new ArchiveReader(binaryFile, { encoding: "random stuff" });
       ok(false, "Should have thrown for bogus encoding label.");
     } catch (e) {
-      ok(e instanceof TypeError, "Expected a TypeError");
+      ok(e instanceof RangeError, "Expected a RangeError");
       finishTest();
     }
   }
 
   function testSteps()
   {
     test1();
     yield undefined;
--- a/dom/base/Console.cpp
+++ b/dom/base/Console.cpp
@@ -40,30 +40,28 @@
 #define MAX_PAGE_COUNTERS 10000
 
 // The maximum stacktrace depth when populating the stacktrace array used for
 // console.trace().
 #define DEFAULT_MAX_STACKTRACE_DEPTH 200
 
 // This tags are used in the Structured Clone Algorithm to move js values from
 // worker thread to main thread
-#define CONSOLE_TAG_STRING JS_SCTAG_USER_MIN
-#define CONSOLE_TAG_BLOB   JS_SCTAG_USER_MIN + 1
+#define CONSOLE_TAG_BLOB   JS_SCTAG_USER_MIN
 
 using namespace mozilla::dom::exceptions;
 using namespace mozilla::dom::workers;
 
 namespace mozilla {
 namespace dom {
 
 struct
 ConsoleStructuredCloneData
 {
   nsCOMPtr<nsISupports> mParent;
-  nsTArray<nsString> mStrings;
   nsTArray<nsRefPtr<FileImpl>> mFiles;
 };
 
 /**
  * Console API in workers uses the Structured Clone Algorithm to move any value
  * from the worker thread to the main-thread. Some object cannot be moved and,
  * in these cases, we convert them to strings.
  * It's not the best, but at least we are able to show something.
@@ -77,32 +75,16 @@ ConsoleStructuredCloneCallbacksRead(JSCo
                                     uint32_t aTag, uint32_t aIndex,
                                     void* aClosure)
 {
   AssertIsOnMainThread();
   ConsoleStructuredCloneData* data =
     static_cast<ConsoleStructuredCloneData*>(aClosure);
   MOZ_ASSERT(data);
 
-  if (aTag == CONSOLE_TAG_STRING) {
-    MOZ_ASSERT(data->mStrings.Length() > aIndex);
-
-    JS::Rooted<JS::Value> value(aCx);
-    if (!xpc::StringToJsval(aCx, data->mStrings.ElementAt(aIndex), &value)) {
-      return nullptr;
-    }
-
-    JS::Rooted<JSObject*> obj(aCx);
-    if (!JS_ValueToObject(aCx, value, &obj)) {
-      return nullptr;
-    }
-
-    return obj;
-  }
-
   if (aTag == CONSOLE_TAG_BLOB) {
     MOZ_ASSERT(data->mFiles.Length() > aIndex);
 
     JS::Rooted<JS::Value> val(aCx);
     {
       nsRefPtr<File> file =
         new File(data->mParent, data->mFiles.ElementAt(aIndex));
       if (!GetOrCreateDOMReflector(aCx, file, &val)) {
@@ -141,27 +123,20 @@ ConsoleStructuredCloneCallbacksWrite(JSC
   }
 
   JS::Rooted<JS::Value> value(aCx, JS::ObjectOrNullValue(aObj));
   JS::Rooted<JSString*> jsString(aCx, JS::ToString(aCx, value));
   if (!jsString) {
     return false;
   }
 
-  nsAutoJSString string;
-  if (!string.init(aCx, jsString)) {
+  if (!JS_WriteString(aWriter, jsString)) {
     return false;
   }
 
-  if (!JS_WriteUint32Pair(aWriter, CONSOLE_TAG_STRING,
-                          data->mStrings.Length())) {
-    return false;
-  }
-
-  data->mStrings.AppendElement(string);
   return true;
 }
 
 static void
 ConsoleStructuredCloneCallbacksError(JSContext* /* aCx */,
                                      uint32_t /* aErrorId */)
 {
   NS_WARNING("Failed to clone data for the Console API in workers.");
--- a/dom/base/WindowNamedPropertiesHandler.cpp
+++ b/dom/base/WindowNamedPropertiesHandler.cpp
@@ -154,17 +154,17 @@ WindowNamedPropertiesHandler::getOwnProp
 bool
 WindowNamedPropertiesHandler::defineProperty(JSContext* aCx,
                                              JS::Handle<JSObject*> aProxy,
                                              JS::Handle<jsid> aId,
                                              JS::MutableHandle<JSPropertyDescriptor> aDesc) const
 {
   ErrorResult rv;
   rv.ThrowTypeError(MSG_DEFINEPROPERTY_ON_GSP);
-  rv.ReportTypeError(aCx);
+  rv.ReportErrorWithMessage(aCx);
   return false;
 }
 
 bool
 WindowNamedPropertiesHandler::ownPropNames(JSContext* aCx,
                                            JS::Handle<JSObject*> aProxy,
                                            unsigned flags,
                                            JS::AutoIdVector& aProps) const
--- a/dom/base/domerr.msg
+++ b/dom/base/domerr.msg
@@ -33,18 +33,16 @@ DOM4_MSG_DEF(DataCloneError, "The object
 DOM4_MSG_DEF(InvalidPointerId, "Invalid pointer id.", NS_ERROR_DOM_INVALID_POINTER_ERR)
 
 /* XXX Should be JavaScript native TypeError */
 DOM4_MSG_DEF(TypeError, "The method parameter is missing or invalid.", NS_ERROR_TYPE_ERR)
 DOM4_MSG_DEF(RangeError, "The method parameter is out of valid range.", NS_ERROR_RANGE_ERR)
 
 /* StringEncoding API errors from http://wiki.whatwg.org/wiki/StringEncoding */
 DOM4_MSG_DEF(EncodingError, "The given encoding is not supported.", NS_ERROR_DOM_ENCODING_NOT_SUPPORTED_ERR)
-DOM4_MSG_DEF(EncodingError, "The encoding must be utf-8, utf-16, or utf-16be.", NS_ERROR_DOM_ENCODING_NOT_UTF_ERR)
-DOM4_MSG_DEF(EncodingError, "The decoder failed to convert.", NS_ERROR_DOM_ENCODING_DECODE_ERR)
 
 /* WebCrypto API errors from http://www.w3.org/TR/WebCryptoAPI/ */
 DOM4_MSG_DEF(UnknownError, "The operation failed for an unknown transient reason", NS_ERROR_DOM_UNKNOWN_ERR)
 DOM4_MSG_DEF(DataError, "Data provided to an operation does not meet requirements", NS_ERROR_DOM_DATA_ERR)
 DOM4_MSG_DEF(OperationError, "The operation failed for an operation-specific reason", NS_ERROR_DOM_OPERATION_ERR)
 
 /* SVG DOM errors from http://www.w3.org/TR/SVG11/svgdom.html */
 
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -45,18 +45,18 @@
 #include "mozilla/jsipc/CrossProcessObjectWrappers.h"
 #include "WorkerPrivate.h"
 #include "nsDOMClassInfo.h"
 
 namespace mozilla {
 namespace dom {
 
 JSErrorFormatString ErrorFormatString[] = {
-#define MSG_DEF(_name, _argc, _str) \
-  { _str, _argc, JSEXN_TYPEERR },
+#define MSG_DEF(_name, _argc, _exn, _str) \
+  { _str, _argc, _exn },
 #include "mozilla/dom/Errors.msg"
 #undef MSG_DEF
 };
 
 const JSErrorFormatString*
 GetErrorMessage(void* aUserRef, const unsigned aErrorNumber)
 {
   MOZ_ASSERT(aErrorNumber < ArrayLength(ErrorFormatString));
@@ -118,48 +118,63 @@ ThrowNoSetterArg(JSContext* aCx, prototy
 } // namespace dom
 
 struct ErrorResult::Message {
   nsTArray<nsString> mArgs;
   dom::ErrNum mErrorNumber;
 };
 
 void
-ErrorResult::ThrowTypeError(const dom::ErrNum errorNumber, ...)
+ErrorResult::ThrowErrorWithMessage(va_list ap, const dom::ErrNum errorNumber,
+                                   nsresult errorType)
 {
-  va_list ap;
-  va_start(ap, errorNumber);
   if (IsJSException()) {
     // We have rooted our mJSException, and we don't have the info
     // needed to unroot here, so just bail.
-    va_end(ap);
     MOZ_ASSERT(false,
-               "Ignoring ThrowTypeError call because we have a JS exception");
+               "Ignoring ThrowErrorWithMessage call because we have a JS exception");
     return;
   }
-  if (IsTypeError()) {
+  if (IsErrorWithMessage()) {
     delete mMessage;
   }
-  mResult = NS_ERROR_TYPE_ERR;
+  mResult = errorType;
   Message* message = new Message();
   message->mErrorNumber = errorNumber;
   uint16_t argCount = dom::GetErrorMessage(nullptr, errorNumber)->argCount;
   MOZ_ASSERT(argCount <= 10);
   argCount = std::min<uint16_t>(argCount, 10);
   while (argCount--) {
     message->mArgs.AppendElement(*va_arg(ap, nsString*));
   }
   mMessage = message;
+}
+
+void
+ErrorResult::ThrowTypeError(const dom::ErrNum errorNumber, ...)
+{
+  va_list ap;
+  va_start(ap, errorNumber);
+  ThrowErrorWithMessage(ap, errorNumber, NS_ERROR_TYPE_ERR);
   va_end(ap);
 }
 
 void
-ErrorResult::ReportTypeError(JSContext* aCx)
+ErrorResult::ThrowRangeError(const dom::ErrNum errorNumber, ...)
 {
-  MOZ_ASSERT(mMessage, "ReportTypeError() can be called only once");
+  va_list ap;
+  va_start(ap, errorNumber);
+  ThrowErrorWithMessage(ap, errorNumber, NS_ERROR_RANGE_ERR);
+  va_end(ap);
+}
+
+void
+ErrorResult::ReportErrorWithMessage(JSContext* aCx)
+{
+  MOZ_ASSERT(mMessage, "ReportErrorWithMessage() can be called only once");
 
   Message* message = mMessage;
   const uint32_t argCount = message->mArgs.Length();
   const char16_t* args[11];
   for (uint32_t i = 0; i < argCount; ++i) {
     args[i] = message->mArgs.ElementAt(i).get();
   }
   args[argCount] = nullptr;
@@ -169,29 +184,29 @@ ErrorResult::ReportTypeError(JSContext* 
                               argCount > 0 ? args : nullptr);
 
   ClearMessage();
 }
 
 void
 ErrorResult::ClearMessage()
 {
-  if (IsTypeError()) {
+  if (IsErrorWithMessage()) {
     delete mMessage;
     mMessage = nullptr;
   }
 }
 
 void
 ErrorResult::ThrowJSException(JSContext* cx, JS::Handle<JS::Value> exn)
 {
   MOZ_ASSERT(mMightHaveUnreportedJSException,
              "Why didn't you tell us you planned to throw a JS exception?");
 
-  if (IsTypeError()) {
+  if (IsErrorWithMessage()) {
     delete mMessage;
   }
 
   // Make sure mJSException is initialized _before_ we try to root it.  But
   // don't set it to exn yet, because we don't want to do that until after we
   // root.
   mJSException.setUndefined();
   if (!js::AddRawValueRoot(cx, &mJSException, "ErrorResult::mJSException")) {
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -98,18 +98,18 @@ ThrowInvalidThis(JSContext* aCx, const J
                  prototypes::ID aProtoId);
 
 inline bool
 ThrowMethodFailedWithDetails(JSContext* cx, ErrorResult& rv,
                              const char* ifaceName,
                              const char* memberName,
                              bool reportJSContentExceptions = false)
 {
-  if (rv.IsTypeError()) {
-    rv.ReportTypeError(cx);
+  if (rv.IsErrorWithMessage()) {
+    rv.ReportErrorWithMessage(cx);
     return false;
   }
   if (rv.IsJSException()) {
     if (reportJSContentExceptions) {
       rv.ReportJSExceptionFromJSImplementation(cx);
     } else {
       rv.ReportJSException(cx);
     }
--- a/dom/bindings/ErrorResult.h
+++ b/dom/bindings/ErrorResult.h
@@ -18,17 +18,17 @@
 #include "nsStringGlue.h"
 #include "mozilla/Assertions.h"
 
 namespace mozilla {
 
 namespace dom {
 
 enum ErrNum {
-#define MSG_DEF(_name, _argc, _str) \
+#define MSG_DEF(_name, _argc, _exn, _str) \
   _name,
 #include "mozilla/dom/Errors.msg"
 #undef MSG_DEF
   Err_Limit
 };
 
 bool
 ThrowErrorMessage(JSContext* aCx, const ErrNum aErrorNumber, ...);
@@ -46,36 +46,38 @@ public:
     // a debug-only warning from gcc 4.6.
     mMessage = nullptr;
     mMightHaveUnreportedJSException = false;
 #endif
   }
 
 #ifdef DEBUG
   ~ErrorResult() {
-    MOZ_ASSERT_IF(IsTypeError(), !mMessage);
+    MOZ_ASSERT_IF(IsErrorWithMessage(), !mMessage);
     MOZ_ASSERT(!mMightHaveUnreportedJSException);
   }
 #endif
 
   void Throw(nsresult rv) {
     MOZ_ASSERT(NS_FAILED(rv), "Please don't try throwing success");
     MOZ_ASSERT(rv != NS_ERROR_TYPE_ERR, "Use ThrowTypeError()");
-    MOZ_ASSERT(!IsTypeError(), "Don't overwite TypeError");
+    MOZ_ASSERT(rv != NS_ERROR_RANGE_ERR, "Use ThrowRangeError()");
+    MOZ_ASSERT(!IsErrorWithMessage(), "Don't overwrite errors with message");
     MOZ_ASSERT(rv != NS_ERROR_DOM_JS_EXCEPTION, "Use ThrowJSException()");
     MOZ_ASSERT(!IsJSException(), "Don't overwrite JS exceptions");
     MOZ_ASSERT(rv != NS_ERROR_XPC_NOT_ENOUGH_ARGS, "Use ThrowNotEnoughArgsError()");
     MOZ_ASSERT(!IsNotEnoughArgsError(), "Don't overwrite not enough args error");
     mResult = rv;
   }
 
   void ThrowTypeError(const dom::ErrNum errorNumber, ...);
-  void ReportTypeError(JSContext* cx);
+  void ThrowRangeError(const dom::ErrNum errorNumber, ...);
+  void ReportErrorWithMessage(JSContext* cx);
   void ClearMessage();
-  bool IsTypeError() const { return ErrorCode() == NS_ERROR_TYPE_ERR; }
+  bool IsErrorWithMessage() const { return ErrorCode() == NS_ERROR_TYPE_ERR || ErrorCode() == NS_ERROR_RANGE_ERR; }
 
   // Facilities for throwing a preexisting JS exception value via this
   // ErrorResult.  The contract is that any code which might end up calling
   // ThrowJSException() must call MightThrowJSException() even if no exception
   // is being thrown.  Code that would call ReportJSException* or
   // StealJSException as needed must first call WouldReportJSException even if
   // this ErrorResult has not failed.
   //
@@ -118,17 +120,18 @@ public:
   // interesting things, like strings or DOM exception types or
   // something if desired.
 
   // Backwards-compat to make conversion simpler.  We don't call
   // Throw() here because people can easily pass success codes to
   // this.
   void operator=(nsresult rv) {
     MOZ_ASSERT(rv != NS_ERROR_TYPE_ERR, "Use ThrowTypeError()");
-    MOZ_ASSERT(!IsTypeError(), "Don't overwite TypeError");
+    MOZ_ASSERT(rv != NS_ERROR_RANGE_ERR, "Use ThrowRangeError()");
+    MOZ_ASSERT(!IsErrorWithMessage(), "Don't overwrite errors with message");
     MOZ_ASSERT(rv != NS_ERROR_DOM_JS_EXCEPTION, "Use ThrowJSException()");
     MOZ_ASSERT(!IsJSException(), "Don't overwrite JS exceptions");
     MOZ_ASSERT(rv != NS_ERROR_XPC_NOT_ENOUGH_ARGS, "Use ThrowNotEnoughArgsError()");
     MOZ_ASSERT(!IsNotEnoughArgsError(), "Don't overwrite not enough args error");
     mResult = rv;
   }
 
   bool Failed() const {
@@ -137,34 +140,36 @@ public:
 
   nsresult ErrorCode() const {
     return mResult;
   }
 
 private:
   nsresult mResult;
   struct Message;
-  // mMessage is set by ThrowTypeError and cleared (and deallocatd) by
-  // ReportTypeError.
+  // mMessage is set by ThrowErrorWithMessage and cleared (and deallocated) by
+  // ReportErrorWithMessage.
   // mJSException is set (and rooted) by ThrowJSException and unrooted
   // by ReportJSException.
   union {
-    Message* mMessage; // valid when IsTypeError()
+    Message* mMessage; // valid when IsErrorWithMessage()
     JS::Value mJSException; // valid when IsJSException()
   };
 
 #ifdef DEBUG
   // Used to keep track of codepaths that might throw JS exceptions,
   // for assertion purposes.
   bool mMightHaveUnreportedJSException;
 #endif
 
   // Not to be implemented, to make sure people always pass this by
   // reference, not by value.
   ErrorResult(const ErrorResult&) = delete;
+  void ThrowErrorWithMessage(va_list ap, const dom::ErrNum errorNumber,
+                             nsresult errorType);
 };
 
 /******************************************************************************
  ** Macros for checking results
  ******************************************************************************/
 
 #define ENSURE_SUCCESS(res, ret)                                          \
   do {                                                                    \
--- a/dom/bindings/Errors.msg
+++ b/dom/bindings/Errors.msg
@@ -14,55 +14,60 @@
  * <ARGUMENT_COUNT> is an integer literal specifying the total number of
  * replaceable arguments in the following format string.
  *
  * <FORMAT_STRING> is a string literal, containing <ARGUMENT_COUNT> sequences
  * {X} where X  is an integer representing the argument number that will
  * be replaced with a string value when the error is reported.
  */
 
-MSG_DEF(MSG_INVALID_ENUM_VALUE, 3, "{0} '{1}' is not a valid value for enumeration {2}.")
-MSG_DEF(MSG_MISSING_ARGUMENTS, 1, "Not enough arguments to {0}.")
-MSG_DEF(MSG_NOT_OBJECT, 1, "{0} is not an object.")
-MSG_DEF(MSG_NOT_CALLABLE, 1, "{0} is not callable.")
-MSG_DEF(MSG_DOES_NOT_IMPLEMENT_INTERFACE, 2, "{0} does not implement interface {1}.")
-MSG_DEF(MSG_METHOD_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 2, "'{0}' called on an object that does not implement interface {1}.")
-MSG_DEF(MSG_METHOD_THIS_UNWRAPPING_DENIED, 1, "Permission to call '{0}' denied.")
-MSG_DEF(MSG_GETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 2, "'{0}' getter called on an object that does not implement interface {1}.")
-MSG_DEF(MSG_GETTER_THIS_UNWRAPPING_DENIED, 1, "Permission to call '{0}' getter denied.")
-MSG_DEF(MSG_SETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 2, "'{0}' setter called on an object that does not implement interface {1}.")
-MSG_DEF(MSG_SETTER_THIS_UNWRAPPING_DENIED, 1, "Permission to call '{0}' setter denied.")
-MSG_DEF(MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 1, "\"this\" object does not implement interface {0}.")
-MSG_DEF(MSG_NOT_IN_UNION, 2, "{0} could not be converted to any of: {1}.")
-MSG_DEF(MSG_ILLEGAL_CONSTRUCTOR, 0, "Illegal constructor.")
-MSG_DEF(MSG_CONSTRUCTOR_WITHOUT_NEW, 1, "Constructor {0} requires 'new'")
-MSG_DEF(MSG_NO_INDEXED_SETTER, 1, "{0} doesn't have an indexed property setter.")
-MSG_DEF(MSG_NO_NAMED_SETTER, 1, "{0} doesn't have a named property setter.")
-MSG_DEF(MSG_ENFORCE_RANGE_NON_FINITE, 1, "Non-finite value is out of range for {0}.")
-MSG_DEF(MSG_ENFORCE_RANGE_OUT_OF_RANGE, 1, "Value is out of range for {0}.")
-MSG_DEF(MSG_NOT_SEQUENCE, 1, "{0} can't be converted to a sequence.")
-MSG_DEF(MSG_NOT_DICTIONARY, 1, "{0} can't be converted to a dictionary.")
-MSG_DEF(MSG_OVERLOAD_RESOLUTION_FAILED, 3, "Argument {0} is not valid for any of the {1}-argument overloads of {2}.")
-MSG_DEF(MSG_GLOBAL_NOT_NATIVE, 0, "Global is not a native object.")
-MSG_DEF(MSG_ENCODING_NOT_SUPPORTED, 1, "The given encoding '{0}' is not supported.")
-MSG_DEF(MSG_DOM_ENCODING_NOT_UTF, 0, "The encoding must be utf-8, utf-16, or utf-16be.")
-MSG_DEF(MSG_NOT_FINITE, 1, "{0} is not a finite floating-point value.")
-MSG_DEF(MSG_INVALID_VERSION, 0, "0 (Zero) is not a valid database version.")
-MSG_DEF(MSG_INVALID_BYTESTRING, 2, "Cannot convert string to ByteString because the character"
+MSG_DEF(MSG_INVALID_ENUM_VALUE, 3, JSEXN_TYPEERR, "{0} '{1}' is not a valid value for enumeration {2}.")
+MSG_DEF(MSG_MISSING_ARGUMENTS, 1, JSEXN_TYPEERR, "Not enough arguments to {0}.")
+MSG_DEF(MSG_NOT_OBJECT, 1, JSEXN_TYPEERR, "{0} is not an object.")
+MSG_DEF(MSG_NOT_CALLABLE, 1, JSEXN_TYPEERR, "{0} is not callable.")
+MSG_DEF(MSG_DOES_NOT_IMPLEMENT_INTERFACE, 2, JSEXN_TYPEERR, "{0} does not implement interface {1}.")
+MSG_DEF(MSG_METHOD_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 2, JSEXN_TYPEERR, "'{0}' called on an object that does not implement interface {1}.")
+MSG_DEF(MSG_METHOD_THIS_UNWRAPPING_DENIED, 1, JSEXN_TYPEERR, "Permission to call '{0}' denied.")
+MSG_DEF(MSG_GETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 2, JSEXN_TYPEERR, "'{0}' getter called on an object that does not implement interface {1}.")
+MSG_DEF(MSG_GETTER_THIS_UNWRAPPING_DENIED, 1, JSEXN_TYPEERR, "Permission to call '{0}' getter denied.")
+MSG_DEF(MSG_SETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 2, JSEXN_TYPEERR, "'{0}' setter called on an object that does not implement interface {1}.")
+MSG_DEF(MSG_SETTER_THIS_UNWRAPPING_DENIED, 1, JSEXN_TYPEERR, "Permission to call '{0}' setter denied.")
+MSG_DEF(MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 1, JSEXN_TYPEERR, "\"this\" object does not implement interface {0}.")
+MSG_DEF(MSG_NOT_IN_UNION, 2, JSEXN_TYPEERR, "{0} could not be converted to any of: {1}.")
+MSG_DEF(MSG_ILLEGAL_CONSTRUCTOR, 0, JSEXN_TYPEERR, "Illegal constructor.")
+MSG_DEF(MSG_CONSTRUCTOR_WITHOUT_NEW, 1, JSEXN_TYPEERR, "Constructor {0} requires 'new'")
+MSG_DEF(MSG_NO_INDEXED_SETTER, 1, JSEXN_TYPEERR, "{0} doesn't have an indexed property setter.")
+MSG_DEF(MSG_NO_NAMED_SETTER, 1, JSEXN_TYPEERR, "{0} doesn't have a named property setter.")
+MSG_DEF(MSG_ENFORCE_RANGE_NON_FINITE, 1, JSEXN_TYPEERR, "Non-finite value is out of range for {0}.")
+MSG_DEF(MSG_ENFORCE_RANGE_OUT_OF_RANGE, 1, JSEXN_TYPEERR, "Value is out of range for {0}.")
+MSG_DEF(MSG_NOT_SEQUENCE, 1, JSEXN_TYPEERR, "{0} can't be converted to a sequence.")
+MSG_DEF(MSG_NOT_DICTIONARY, 1, JSEXN_TYPEERR, "{0} can't be converted to a dictionary.")
+MSG_DEF(MSG_OVERLOAD_RESOLUTION_FAILED, 3, JSEXN_TYPEERR, "Argument {0} is not valid for any of the {1}-argument overloads of {2}.")
+MSG_DEF(MSG_GLOBAL_NOT_NATIVE, 0, JSEXN_TYPEERR, "Global is not a native object.")
+MSG_DEF(MSG_ENCODING_NOT_SUPPORTED, 1, JSEXN_RANGEERR, "The given encoding '{0}' is not supported.")
+MSG_DEF(MSG_DOM_ENCODING_NOT_UTF, 0, JSEXN_RANGEERR, "The encoding must be utf-8, utf-16, or utf-16be.")
+MSG_DEF(MSG_DOM_DECODING_FAILED, 0, JSEXN_TYPEERR, "Decoding failed.")
+MSG_DEF(MSG_NOT_FINITE, 1, JSEXN_TYPEERR, "{0} is not a finite floating-point value.")
+MSG_DEF(MSG_INVALID_VERSION, 0, JSEXN_TYPEERR, "0 (Zero) is not a valid database version.")
+MSG_DEF(MSG_INVALID_BYTESTRING, 2, JSEXN_TYPEERR, "Cannot convert string to ByteString because the character"
         " at index {0} has value {1} which is greater than 255.")
-MSG_DEF(MSG_NOT_DATE, 1, "{0} is not a date.")
-MSG_DEF(MSG_INVALID_ADVANCE_COUNT, 0, "0 (Zero) is not a valid advance count.")
-MSG_DEF(MSG_DEFINEPROPERTY_ON_GSP, 0, "Not allowed to define a property on the named properties object.")
-MSG_DEF(MSG_INVALID_URL, 1, "{0} is not a valid URL.")
-MSG_DEF(MSG_METADATA_NOT_CONFIGURED, 0, "Either size or lastModified should be true.")
-MSG_DEF(MSG_INVALID_READ_SIZE, 0, "0 (Zero) is not a valid read size.")
-MSG_DEF(MSG_HEADERS_IMMUTABLE, 0, "Headers are immutable and cannot be modified.")
-MSG_DEF(MSG_INVALID_HEADER_NAME, 1, "{0} is an invalid header name.")
-MSG_DEF(MSG_INVALID_HEADER_VALUE, 1, "{0} is an invalid header value.")
-MSG_DEF(MSG_INVALID_HEADER_SEQUENCE, 0, "Headers require name/value tuples when being initialized by a sequence.")
-MSG_DEF(MSG_PERMISSION_DENIED_TO_PASS_ARG, 1, "Permission denied to pass cross-origin object as {0}.")
-MSG_DEF(MSG_MISSING_REQUIRED_DICTIONARY_MEMBER, 1, "Missing required {0}.")
-MSG_DEF(MSG_INVALID_REQUEST_METHOD, 1, "Invalid request method {0}.")
-MSG_DEF(MSG_REQUEST_BODY_CONSUMED_ERROR, 0, "Request body has already been consumed.")
-MSG_DEF(MSG_RESPONSE_INVALID_STATUSTEXT_ERROR, 0, "Response statusText may not contain newline or carriage return.")
-MSG_DEF(MSG_FETCH_FAILED, 0, "NetworkError when attempting to fetch resource.")
-MSG_DEF(MSG_NO_BODY_ALLOWED_FOR_GET_AND_HEAD, 0, "HEAD or GET Request cannot have a body.")
-MSG_DEF(MSG_DEFINE_NON_CONFIGURABLE_PROP_ON_WINDOW, 0, "Not allowed to define a non-configurable property on the WindowProxy object")
+MSG_DEF(MSG_NOT_DATE, 1, JSEXN_TYPEERR, "{0} is not a date.")
+MSG_DEF(MSG_INVALID_ADVANCE_COUNT, 0, JSEXN_TYPEERR, "0 (Zero) is not a valid advance count.")
+MSG_DEF(MSG_DEFINEPROPERTY_ON_GSP, 0, JSEXN_TYPEERR, "Not allowed to define a property on the named properties object.")
+MSG_DEF(MSG_INVALID_URL, 1, JSEXN_TYPEERR, "{0} is not a valid URL.")
+MSG_DEF(MSG_METADATA_NOT_CONFIGURED, 0, JSEXN_TYPEERR, "Either size or lastModified should be true.")
+MSG_DEF(MSG_INVALID_READ_SIZE, 0, JSEXN_TYPEERR, "0 (Zero) is not a valid read size.")
+MSG_DEF(MSG_HEADERS_IMMUTABLE, 0, JSEXN_TYPEERR, "Headers are immutable and cannot be modified.")
+MSG_DEF(MSG_INVALID_HEADER_NAME, 1, JSEXN_TYPEERR, "{0} is an invalid header name.")
+MSG_DEF(MSG_INVALID_HEADER_VALUE, 1, JSEXN_TYPEERR, "{0} is an invalid header value.")
+MSG_DEF(MSG_INVALID_HEADER_SEQUENCE, 0, JSEXN_TYPEERR, "Headers require name/value tuples when being initialized by a sequence.")
+MSG_DEF(MSG_PERMISSION_DENIED_TO_PASS_ARG, 1, JSEXN_TYPEERR, "Permission denied to pass cross-origin object as {0}.")
+MSG_DEF(MSG_MISSING_REQUIRED_DICTIONARY_MEMBER, 1, JSEXN_TYPEERR, "Missing required {0}.")
+MSG_DEF(MSG_INVALID_REQUEST_METHOD, 1, JSEXN_TYPEERR, "Invalid request method {0}.")
+MSG_DEF(MSG_REQUEST_BODY_CONSUMED_ERROR, 0, JSEXN_TYPEERR, "Request body has already been consumed.")
+MSG_DEF(MSG_RESPONSE_INVALID_STATUSTEXT_ERROR, 0, JSEXN_TYPEERR, "Response statusText may not contain newline or carriage return.")
+MSG_DEF(MSG_FETCH_FAILED, 0, JSEXN_TYPEERR, "NetworkError when attempting to fetch resource.")
+MSG_DEF(MSG_NO_BODY_ALLOWED_FOR_GET_AND_HEAD, 0, JSEXN_TYPEERR, "HEAD or GET Request cannot have a body.")
+MSG_DEF(MSG_DEFINE_NON_CONFIGURABLE_PROP_ON_WINDOW, 0, JSEXN_TYPEERR, "Not allowed to define a non-configurable property on the WindowProxy object")
+MSG_DEF(MSG_INVALID_ZOOMANDPAN_VALUE_ERROR, 0, JSEXN_RANGEERR, "Invalid zoom and pan value.")
+MSG_DEF(MSG_INVALID_TRANSFORM_ANGLE_ERROR, 0, JSEXN_RANGEERR, "Invalid transform angle.")
+MSG_DEF(MSG_INVALID_RESPONSE_STATUSCODE_ERROR, 0, JSEXN_RANGEERR, "Invalid response status code.")
+MSG_DEF(MSG_INVALID_REDIRECT_STATUSCODE_ERROR, 0, JSEXN_RANGEERR, "Invalid redirect status code.")
--- a/dom/canvas/WebGLShaderValidator.cpp
+++ b/dom/canvas/WebGLShaderValidator.cpp
@@ -162,51 +162,31 @@ ShaderValidator::ValidateAndTranslate(co
 
     const char* const parts[] = {
         source
     };
     return ShCompile(mHandle, parts, ArrayLength(parts), mCompileOptions);
 }
 
 void
-ShaderValidator::GetInfo(ShShaderInfo pname, size_t* params) const
-{
-    MOZ_ASSERT(mHasRun);
-
-    ShGetInfo(mHandle, pname, params);
-}
-
-void
 ShaderValidator::GetInfoLog(nsACString* out) const
 {
     MOZ_ASSERT(mHasRun);
 
-    size_t lenWithNull = 0;
-    GetInfo(SH_INFO_LOG_LENGTH, &lenWithNull);
-    MOZ_ASSERT(lenWithNull >= 1);
-
-    // SetLength allocates len+1, for the null-term.
-    out->SetLength(lenWithNull - 1);
-
-    ShGetInfoLog(mHandle, out->BeginWriting());
+    const std::string &log = ShGetInfoLog(mHandle);
+    out->Assign(log.data(), log.length());
 }
 
 void
 ShaderValidator::GetOutput(nsACString* out) const
 {
     MOZ_ASSERT(mHasRun);
 
-    size_t lenWithNull = 0;
-    GetInfo(SH_OBJECT_CODE_LENGTH, &lenWithNull);
-    MOZ_ASSERT(lenWithNull >= 1);
-
-    // SetLength allocates len+1, for the null-term.
-    out->SetLength(lenWithNull - 1);
-
-    ShGetObjectCode(mHandle, out->BeginWriting());
+    const std::string &output = ShGetObjectCode(mHandle);
+    out->Assign(output.data(), output.length());
 }
 
 template<size_t N>
 static bool
 StartsWith(const std::string& haystack, const char (&needle)[N])
 {
     return haystack.compare(0, N - 1, needle) == 0;
 }
--- a/dom/canvas/WebGLShaderValidator.h
+++ b/dom/canvas/WebGLShaderValidator.h
@@ -32,17 +32,16 @@ private:
         , mCompileOptions(compileOptions)
         , mHasRun(false)
     { }
 
 public:
     ~ShaderValidator();
 
     bool ValidateAndTranslate(const char* source);
-    void GetInfo(ShShaderInfo pname, size_t* params) const;
     void GetInfoLog(nsACString* out) const;
     void GetOutput(nsACString* out) const;
     bool CanLinkTo(const ShaderValidator* prev, nsCString* const out_log) const;
     size_t CalcNumSamplerUniforms() const;
 
     bool FindAttribUserNameByMappedName(const std::string& mappedName,
                                         const std::string** const out_userName) const;
 
--- a/dom/contacts/fallback/ContactDB.jsm
+++ b/dom/contacts/fallback/ContactDB.jsm
@@ -119,17 +119,24 @@ ContactDB.prototype = {
       if (!contactsFile || (contactsFile && !contactsFile.exists())) {
         // For b2g desktop
         contactsFile = jsm.FileUtils.getFile("ProfD", ["contacts.json"], false);
         if (!contactsFile || (contactsFile && !contactsFile.exists())) {
           return;
         }
       }
 
-      let chan = jsm.NetUtil.newChannel(contactsFile);
+      let chan = jsm.NetUtil.newChannel2(contactsFile,
+                                         null,
+                                         null,
+                                         null,      // aLoadingNode
+                                         Services.scriptSecurityManager.getSystemPrincipal(),
+                                         null,      // aTriggeringPrincipal
+                                         Ci.nsILoadInfo.SEC_NORMAL,
+                                         Ci.nsIContentPolicy.TYPE_OTHER);
       let stream = chan.open();
       // Obtain a converter to read from a UTF-8 encoded input stream.
       let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
                       .createInstance(Ci.nsIScriptableUnicodeConverter);
       converter.charset = "UTF-8";
       let rawstr = converter.ConvertToUnicode(jsm.NetUtil.readInputStreamToString(
                                               stream,
                                               stream.available()) || "");
--- a/dom/encoding/TextDecoder.cpp
+++ b/dom/encoding/TextDecoder.cpp
@@ -15,21 +15,22 @@ namespace dom {
 static const char16_t kReplacementChar = static_cast<char16_t>(0xFFFD);
 
 void
 TextDecoder::Init(const nsAString& aLabel, const bool aFatal,
                   ErrorResult& aRv)
 {
   nsAutoCString encoding;
   // Let encoding be the result of getting an encoding from label.
-  // If encoding is failure or replacement, throw a TypeError.
+  // If encoding is failure or replacement, throw a RangeError
+  // (https://encoding.spec.whatwg.org/#dom-textdecoder).
   if (!EncodingUtils::FindEncodingForLabelNoReplacement(aLabel, encoding)) {
     nsAutoString label(aLabel);
     EncodingUtils::TrimSpaceCharacters(label);
-    aRv.ThrowTypeError(MSG_ENCODING_NOT_SUPPORTED, &label);
+    aRv.ThrowRangeError(MSG_ENCODING_NOT_SUPPORTED, &label);
     return;
   }
   InitWithEncoding(encoding, aFatal);
 }
 
 void
 TextDecoder::InitWithEncoding(const nsACString& aEncoding, const bool aFatal)
 {
@@ -76,27 +77,27 @@ TextDecoder::Decode(const char* aInput, 
   aOutDecodedString.Append(buf, outLen);
 
   // If the internal streaming flag of the decoder object is not set,
   // then reset the encoding algorithm state to the default values
   if (!aStream) {
     mDecoder->Reset();
     if (rv == NS_OK_UDEC_MOREINPUT) {
       if (mFatal) {
-        aRv.Throw(NS_ERROR_DOM_ENCODING_DECODE_ERR);
+        aRv.ThrowTypeError(MSG_DOM_DECODING_FAILED);
       } else {
         // Need to emit a decode error manually
         // to simulate the EOF handling of the Encoding spec.
         aOutDecodedString.Append(kReplacementChar);
       }
     }
   }
 
   if (NS_FAILED(rv)) {
-    aRv.Throw(NS_ERROR_DOM_ENCODING_DECODE_ERR);
+    aRv.ThrowTypeError(MSG_DOM_DECODING_FAILED);
   }
 }
 
 void
 TextDecoder::Decode(const Optional<ArrayBufferViewOrArrayBuffer>& aBuffer,
                     const TextDecodeOptions& aOptions,
                     nsAString& aOutDecodedString,
                     ErrorResult& aRv)
--- a/dom/encoding/TextEncoder.cpp
+++ b/dom/encoding/TextEncoder.cpp
@@ -13,26 +13,26 @@ namespace dom {
 void
 TextEncoder::Init(const nsAString& aEncoding, ErrorResult& aRv)
 {
   nsAutoString label(aEncoding);
   EncodingUtils::TrimSpaceCharacters(label);
 
   // Let encoding be the result of getting an encoding from label.
   // If encoding is failure, or is none of utf-8, utf-16, and utf-16be,
-  // throw a TypeError.
+  // throw a RangeError (https://encoding.spec.whatwg.org/#dom-textencoder).
   if (!EncodingUtils::FindEncodingForLabel(label, mEncoding)) {
-    aRv.ThrowTypeError(MSG_ENCODING_NOT_SUPPORTED, &label);
+    aRv.ThrowRangeError(MSG_ENCODING_NOT_SUPPORTED, &label);
     return;
   }
 
   if (!mEncoding.EqualsLiteral("UTF-8") &&
       !mEncoding.EqualsLiteral("UTF-16LE") &&
       !mEncoding.EqualsLiteral("UTF-16BE")) {
-    aRv.ThrowTypeError(MSG_DOM_ENCODING_NOT_UTF);
+    aRv.ThrowRangeError(MSG_DOM_ENCODING_NOT_UTF);
     return;
   }
 
   // Create an encoder object for mEncoding.
   mEncoder = EncodingUtils::EncoderForEncoding(mEncoding);
 }
 
 void
--- a/dom/encoding/test/test_BOMEncoding.js
+++ b/dom/encoding/test/test_BOMEncoding.js
@@ -30,28 +30,28 @@ function testBOMEncodingUTF8() {
   // test valid encoding provided with valid byte OM also provided.
   data = [0xEF, 0xBB, 0xBF, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27];
   expectedString = " !\"#$%&'";
   testBOMCharset({encoding: "utf-8", data: data, expected: expectedString,
                   msg: "valid utf-8 encoding provided with VALID utf-8 BOM test."});
 
   // test valid encoding provided with invalid byte OM also provided.
   data = [0xFF, 0xFE, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27];
-  testBOMCharset({encoding: "utf-8", fatal: true, data: data, error: "EncodingError",
+  testBOMCharset({encoding: "utf-8", fatal: true, data: data, error: "TypeError",
                   msg: "valid utf-8 encoding provided with invalid utf-8 fatal BOM test."});
 
   // test valid encoding provided with invalid byte OM also provided.
   data = [0xFF, 0xFE, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27];
   expectedString = "\ufffd\ufffd !\"#$%&'";
   testBOMCharset({encoding: "utf-8", data: data, expected: expectedString,
                   msg: "valid utf-8 encoding provided with invalid utf-8 BOM test."});
 
   // test empty encoding provided with invalid byte OM also provided.
   data = [0xFF, 0xFE, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27];
-  testBOMCharset({encoding: "", data: data, error: "TypeError",
+  testBOMCharset({encoding: "", data: data, error: "RangeError",
                   msg: "empty encoding provided with invalid utf-8 BOM test."});
 }
 
 function testMoreBOMEncoding() {
   var expectedString = "\"\u0412\u0441\u0435 \u0441\u0447\u0430\u0441\u0442\u043B\u0438\u0432\u044B\u0435 \u0441\u0435\u043C\u044C\u0438 \u043F\u043E\u0445\u043E\u0436\u0438 \u0434\u0440\u0443\u0433 \u043D\u0430 \u0434\u0440\u0443\u0433\u0430, \u043A\u0430\u0436\u0434\u0430\u044F \u043D\u0435\u0441\u0447\u0430\u0441\u0442\u043B\u0438\u0432\u0430\u044F \u0441\u0435\u043C\u044C\u044F \u043D\u0435\u0441\u0447\u0430\u0441\u0442\u043B\u0438\u0432\u0430 \u043F\u043E-\u0441\u0432\u043E\u0435\u043C\u0443.\"";
 
  // Testing user provided encoding is UTF-16BE & bom encoding is utf-16le
   var data = [0xFF, 0xFE, 0x00, 0x22, 0x04, 0x12, 0x04, 0x41, 0x04, 0x35, 0x00, 0x20, 0x04, 0x41, 0x04, 0x47, 0x04, 0x30, 0x04, 0x41, 0x04, 0x42, 0x04, 0x3B, 0x04, 0x38, 0x04, 0x32, 0x04, 0x4B, 0x04, 0x35, 0x00, 0x20, 0x04, 0x41, 0x04, 0x35, 0x04, 0x3C, 0x04, 0x4C, 0x04, 0x38, 0x00, 0x20, 0x04, 0x3F, 0x04, 0x3E, 0x04, 0x45, 0x04, 0x3E, 0x04, 0x36, 0x04, 0x38, 0x00, 0x20, 0x04, 0x34, 0x04, 0x40, 0x04, 0x43, 0x04, 0x33, 0x00, 0x20, 0x04, 0x3D, 0x04, 0x30, 0x00, 0x20, 0x04, 0x34, 0x04, 0x40, 0x04, 0x43, 0x04, 0x33, 0x04, 0x30, 0x00, 0x2C, 0x00, 0x20, 0x04, 0x3A, 0x04, 0x30, 0x04, 0x36, 0x04, 0x34, 0x04, 0x30, 0x04, 0x4F, 0x00, 0x20, 0x04, 0x3D, 0x04, 0x35, 0x04, 0x41, 0x04, 0x47, 0x04, 0x30, 0x04, 0x41, 0x04, 0x42, 0x04, 0x3B, 0x04, 0x38, 0x04, 0x32, 0x04, 0x30, 0x04, 0x4F, 0x00, 0x20, 0x04, 0x41, 0x04, 0x35, 0x04, 0x3C, 0x04, 0x4C, 0x04, 0x4F, 0x00, 0x20, 0x04, 0x3D, 0x04, 0x35, 0x04, 0x41, 0x04, 0x47, 0x04, 0x30, 0x04, 0x41, 0x04, 0x42, 0x04, 0x3B, 0x04, 0x38, 0x04, 0x32, 0x04, 0x30, 0x00, 0x20, 0x04, 0x3F, 0x04, 0x3E, 0x00, 0x2D, 0x04, 0x41, 0x04, 0x32, 0x04, 0x3E, 0x04, 0x35, 0x04, 0x3C, 0x04, 0x43, 0x00, 0x2E, 0x00, 0x22];
@@ -83,33 +83,33 @@ function testMoreBOMEncoding() {
                   msg: "test decoder BOM encoding for utf-16 fatal."});
 
   testBOMCharset({encoding: "utf-16", data: dataUTF16, expected: expectedString,
                   msg: "test decoder BOM encoding for utf-16."});
 
   // Testing user provided encoding is UTF-8 & bom encoding is utf-16be
   data = [0xFE, 0xFF, 0x22, 0xd0, 0x92, 0xd1, 0x81, 0xd0, 0xb5, 0x20, 0xd1, 0x81, 0xd1, 0x87, 0xd0, 0xb0, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xbb, 0xd0, 0xb8, 0xd0, 0xb2, 0xd1, 0x8b, 0xd0, 0xb5, 0x20, 0xd1, 0x81, 0xd0, 0xb5, 0xd0, 0xbc, 0xd1, 0x8c, 0xd0, 0xb8, 0x20, 0xd0, 0xbf, 0xd0, 0xbe, 0xd1, 0x85, 0xd0, 0xbe, 0xd0, 0xb6, 0xd0, 0xb8, 0x20, 0xd0, 0xb4, 0xd1, 0x80, 0xd1, 0x83, 0xd0, 0xb3, 0x20, 0xd0, 0xbd, 0xd0, 0xb0, 0x20, 0xd0, 0xb4, 0xd1, 0x80, 0xd1, 0x83, 0xd0, 0xb3, 0xd0, 0xb0, 0x2c, 0x20, 0xd0, 0xba, 0xd0, 0xb0, 0xd0, 0xb6, 0xd0, 0xb4, 0xd0, 0xb0, 0xd1, 0x8f, 0x20, 0xd0, 0xbd, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x87, 0xd0, 0xb0, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xbb, 0xd0, 0xb8, 0xd0, 0xb2, 0xd0, 0xb0, 0xd1, 0x8f, 0x20, 0xd1, 0x81, 0xd0, 0xb5, 0xd0, 0xbc, 0xd1, 0x8c, 0xd1, 0x8f, 0x20, 0xd0, 0xbd, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x87, 0xd0, 0xb0, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xbb, 0xd0, 0xb8, 0xd0, 0xb2, 0xd0, 0xb0, 0x20, 0xd0, 0xbf, 0xd0, 0xbe, 0x2d, 0xd1, 0x81, 0xd0, 0xb2, 0xd0, 0xbe, 0xd0, 0xb5, 0xd0, 0xbc, 0xd1, 0x83, 0x2e, 0x22];
 
-  testBOMCharset({encoding: "utf-8", fatal: true, data: data, error: "EncodingError",
+  testBOMCharset({encoding: "utf-8", fatal: true, data: data, error: "TypeError",
                   msg: "test decoder invalid BOM encoding for valid utf-8 fatal provided label."});
 
   testBOMCharset({encoding: "utf-8", data: data, expected: "\ufffd\ufffd" + expectedString,
                   msg: "test decoder invalid BOM encoding for valid utf-8 provided label."});
 
   // Testing user provided encoding is non-UTF & bom encoding is utf-16be
   data = [0xFE, 0xFF, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe];
 
   expectedString = "\u03CE\uFFFD\u2019\xA3\u20AC\u20AF\xA6\xA7\xA8\xA9\u037A\xAB\xAC\xAD\u2015"
                  + "\xB0\xB1\xB2\xB3\u0384\u0385\u0386\xB7\u0388\u0389\u038A\xBB\u038C\xBD\u038E\u038F"
                  + "\u0390\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039A\u039B\u039C\u039D\u039E\u039F"
                  + "\u03A0\u03A1\u03A3\u03A4\u03A5\u03A6\u03A7\u03A8\u03A9\u03AA\u03AB\u03AC\u03AD\u03AE\u03AF"
                  + "\u03B0\u03B1\u03B2\u03B3\u03B4\u03B5\u03B6\u03B7\u03B8\u03B9\u03BA\u03BB\u03BC\u03BD\u03BE\u03BF"
                  + "\u03C0\u03C1\u03C2\u03C3\u03C4\u03C5\u03C6\u03C7\u03C8\u03C9\u03CA\u03CB\u03CC\u03CD\u03CE";
 
-  testBOMCharset({encoding: "greek", fatal: true, data: data, error: "EncodingError",
+  testBOMCharset({encoding: "greek", fatal: true, data: data, error: "TypeError",
                   msg: "test decoder encoding provided with invalid BOM encoding for greek."});
 
   testBOMCharset({encoding: "greek", data: data, expected: expectedString,
                   msg: "test decoder encoding provided with invalid BOM encoding for greek."});
 }
 
 function testBOMCharset(test)
 {
--- a/dom/encoding/test/test_TextDecoder.js
+++ b/dom/encoding/test/test_TextDecoder.js
@@ -63,35 +63,48 @@ function testConstructorFatalOption(data
 
   //invalid string to decode passed, fatal = true
   testCharset({fatal: true, encoding: "iso-8859-11", input: [], expected: "",
     msg: "constructor fatal option set to true test."});
 }
 
 function testConstructorEncodingOption(aData, aExpectedString)
 {
+  function errorMessage(encoding) {
+    return `The given encoding '${String(encoding).trim()}' is not supported.`;
+  }
+
   // valid encoding passed
-  testCharset({encoding: "iso-8859-11", input: aData, expected: aExpectedString,
+  var encoding = "iso-8859-11";
+  testCharset({encoding: encoding, input: aData, expected: aExpectedString,
     msg: "decoder testing constructor valid encoding."});
 
+  // passing spaces for encoding
+  encoding = "   ";
+  testCharset({encoding: encoding, input: aData, error: "RangeError",
+    errorMessage: errorMessage(encoding),
+    msg: "constructor encoding, spaces encoding test."});
+
   // invalid encoding passed
-  testCharset({encoding: "asdfasdf", input: aData, error: "TypeError",
+  encoding = "asdfasdf";
+  testCharset({encoding: encoding, input: aData, error: "RangeError",
+    errorMessage: errorMessage(encoding),
     msg: "constructor encoding, invalid encoding test."});
 
-  // passing spaces for encoding
-  testCharset({encoding: "   ", input: aData, error: "TypeError",
-    msg: "constructor encoding, spaces encoding test."});
-
-  // passing null for encoding
-  testCharset({encoding: null, input: aData, error: "TypeError",
+  // null encoding passed
+  encoding = null;
+  testCharset({encoding: encoding, input: aData, error: "RangeError",
+    errorMessage: errorMessage(encoding),
     msg: "constructor encoding, \"null\" encoding test."});
 
   // empty encoding passed
-  testCharset({encoding: "", input: aData, error: "TypeError",
-    msg: "constuctor encoding, empty encoding test."});
+  encoding = "";
+  testCharset({encoding: encoding, input: aData, error: "RangeError",
+    errorMessage: errorMessage(encoding),
+    msg: "constructor encoding, empty encoding test."});
 
   // replacement character test
   aExpectedString = "\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd"
                   + "\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd"
                   + "\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd"
                   + "\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd"
                   + "\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd"
                   + "\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd"
@@ -165,18 +178,18 @@ function testDecodeStreamOption(data, ex
   ], msg: "decode() stream test two."});
 
   testCharset({encoding: "utf-8", array: [
     {input: [0xC2], expected: "\uFFFD"},
     {input: [0x80], expected: "\uFFFD"},
   ], msg: "decode() stream test utf-8."});
 
   testCharset({encoding: "utf-8", fatal: true, array: [
-    {input: [0xC2], error: "EncodingError"},
-    {input: [0x80], error: "EncodingError"},
+    {input: [0xC2], error: "TypeError"},
+    {input: [0x80], error: "TypeError"},
   ], msg: "decode() stream test utf-8 fatal."});
 }
 
 function testDecodeStreamCompositions() {
   var tests = [
     {encoding: "utf-8", input: [0xC2,0x80], expected: ["","\x80"]},
     {encoding: "utf-8", input: [0xEF,0xBB,0xBF,0xC2,0x80], expected: ["","","","","\x80"]},
     {encoding: "utf-16", input: [0x01,0x00], expected: ["","\x01"]},
@@ -346,17 +359,17 @@ function testDecoderGetEncoding()
     {encoding: "big5-hkscs", labels: ["big5-hkscs"]},
     {encoding: "euc-jp", labels: ["cseucpkdfmtjapanese", "euc-jp", "x-euc-jp"]},
     {encoding: "iso-2022-jp", labels: ["csiso2022jp", "iso-2022-jp"]},
     {encoding: "shift_jis", labels: ["csshiftjis", "ms_kanji", "shift-jis", "shift_jis", "sjis", "windows-31j", "x-sjis"]},
     {encoding: "euc-kr", labels: ["cseuckr", "csksc56011987", "euc-kr", "iso-ir-149", "korean", "ks_c_5601-1987", "ks_c_5601-1989", "ksc5601", "ksc_5601", "windows-949"]},
     {encoding: "utf-16le", labels: ["utf-16", "utf-16le"]},
     {encoding: "utf-16be", labels: ["utf-16be"]},
     {encoding: "x-user-defined", labels: ["x-user-defined"]},
-    {error: "TypeError", labels: ["x-windows-949", "\u0130SO-8859-1", "csiso2022kr", "iso-2022-kr", "iso-2022-cn", "iso-2022-cn-ext", "replacement", "hz-gb-2312"]},
+    {error: "RangeError", labels: ["x-windows-949", "\u0130SO-8859-1", "csiso2022kr", "iso-2022-kr", "iso-2022-cn", "iso-2022-cn-ext", "replacement", "hz-gb-2312"]},
   ];
 
   for (var le of labelEncodings) {
     for (var label of le.labels) {
       try {
         var decoder = new TextDecoder(label);
       } catch (e) {
         assert_true(!!le.error, label + " shoud not throw " + e.name);
@@ -371,16 +384,19 @@ function testDecoderGetEncoding()
 
 function testCharset(test)
 {
   try {
     var fatal = test.fatal ? {fatal: test.fatal} : null;
     var decoder = new TextDecoder(test.encoding, fatal);
   } catch (e) {
     assert_equals(e.name, test.error, test.msg + " error thrown from the constructor.");
+    if (test.errorMessage) {
+      assert_equals(e.message, test.errorMessage, test.msg + " error thrown from the constructor.");
+    }
     return;
   }
 
   var array = test.array || [test];
   var num_strings = array.length;
   for (var i = 0; i < num_strings; i++) {
     var decodeView = array[i].input !== null ? new Uint8Array(array[i].input) : null;
     var stream = array[i].stream ? {stream: array[i].stream} : null;
@@ -434,16 +450,16 @@ function testInvalid2022JP()
   ];
 
   var failureCount = 0;
   inputs.forEach(function(input) {
     try {
       // decode() should never throw unless {fatal: true} is specified
       (new TextDecoder("iso-2022-jp")).decode(new Uint8Array(input));
     } catch (e) {
-      if (e.name !== "EncodingError") {
+      if (e.name !== "TypeError") {
         throw e;
       }
       failureCount++;
     }
   });
   assert_equals(failureCount, 0, failureCount + " of " + inputs.length + " tests failed");
 }
--- a/dom/encoding/test/test_TextEncoder.js
+++ b/dom/encoding/test/test_TextEncoder.js
@@ -85,41 +85,54 @@ function testEncodeUTF16ToUTF16()
                   0x57, 0x0E, 0x58, 0x0E, 0x59, 0x0E, 0x5A, 0x0E, 0x5B, 0x0E];
 
   testSingleString({encoding: "Utf-16", input: data, expected: expected,
     msg: "testing encoding from utf-16 to utf-16 zero."});
 }
 
 function testConstructorEncodingOption(aData, aExpectedString)
 {
+  function errorMessage(encoding) {
+    return `The given encoding '${String(encoding).trim()}' is not supported.`;
+  }
+
   // valid encoding passed
-  testSingleString({encoding: "UTF-8", input: aData, expected: aExpectedString,
+  var encoding = "UTF-8";
+  testSingleString({encoding: encoding, input: aData, expected: aExpectedString,
     msg: "testing encoding with valid utf-8 encoding."});
 
   // passing spaces for encoding
-  testSingleString({encoding: "   ", input: aData, error: "TypeError",
+  encoding = "   ";
+  testSingleString({encoding: encoding, input: aData, error: "RangeError",
+    errorMessage: errorMessage(encoding),
     msg: "constructor encoding, spaces encoding test."});
 
   // invalid encoding passed
-  testSingleString({encoding: "asdfasdf", input: aData, error: "TypeError",
+  encoding = "asdfasdf";
+  testSingleString({encoding: encoding, input: aData, error: "RangeError",
+    errorMessage: errorMessage(encoding),
     msg: "constructor encoding, invalid encoding test."});
 
   // null encoding passed
-  testSingleString({encoding: null, input: aData, error: "TypeError",
+  encoding = null;
+  testSingleString({encoding: encoding, input: aData, error: "RangeError",
+    errorMessage: errorMessage(encoding),
     msg: "constructor encoding, \"null\" encoding test."});
 
-  // null encoding passed
-  testSingleString({encoding: "", input: aData, error: "TypeError",
+  // empty encoding passed
+  encoding = "";
+  testSingleString({encoding: encoding, input: aData, error: "RangeError",
+    errorMessage: errorMessage(encoding),
     msg: "constructor encoding, empty encoding test."});
 }
 
 function testEncodingValues(aData, aExpectedString)
 {
   var encoding = "ISO-8859-11";
-  testSingleString({encoding: aData, input: encoding, error: "TypeError",
+  testSingleString({encoding: aData, input: encoding, error: "RangeError",
     msg: "encoder encoding values test."});
 }
 
 function testInputString(aData, aExpectedString)
 {
   //Test null input string
   testSingleString({encoding: "utf-8", input: "", expected: [],
     msg: "encoder null input string test."});
@@ -131,17 +144,20 @@ function testInputString(aData, aExpecte
 
 function testSingleString(test)
 {
   var outText;
   try {
     var stream = test.stream ? {stream: true} : null;
     outText = (new TextEncoder(test.encoding)).encode(test.input, stream);
   } catch (e) {
-    assert_equals(e.name, test.error, test.msg);
+    assert_equals(e.name, test.error, test.msg + " error thrown from the constructor.");
+    if (test.errorMessage) {
+      assert_equals(e.message, test.errorMessage, test.msg + " error thrown from the constructor.");
+    }
     return;
   }
   assert_true(!test.error, test.msg);
 
   if (outText.length !== test.expected.length) {
     assert_equals(outText.length, test.expected.length, test.msg + " length mismatch");
     return;
   }
--- a/dom/encoding/test/unit/test_misc.js
+++ b/dom/encoding/test/unit/test_misc.js
@@ -38,17 +38,17 @@ test(
       { encoding: 'utf-16le', input: [0x00, 0xd8, 0x00, 0x00] }, // surrogate half
       { encoding: 'utf-16le', input: [0x00, 0xdc, 0x00, 0x00] }, // trail surrogate
       { encoding: 'utf-16le', input: [0x00, 0xdc, 0x00, 0xd8] }  // swapped surrogates
       // TODO: Single byte encoding cases
     ];
 
     bad.forEach(
       function(t) {
-        assert_throws({name: 'EncodingError'}, function () {
+        assert_throws({name: 'TypeError'}, function () {
           new TextDecoder(t.encoding, {fatal: true}).decode(new Uint8Array(t.input));
         });
       });
   },
   "fatal flag"
 );
 
 test(
@@ -181,25 +181,25 @@ test(
       //assert_array_equals(new TextEncoder(encoding).encode(string), bytes, encoding);
     });
   },
   "Supersets of ASCII decode ASCII correctly"
 );
 
 test(
   function () {
-    assert_throws({name: 'EncodingError'}, function() { new TextDecoder("utf-8", {fatal: true}).decode(new Uint8Array([0xff])); });
+    assert_throws({name: 'TypeError'}, function() { new TextDecoder("utf-8", {fatal: true}).decode(new Uint8Array([0xff])); });
     // This should not hang:
     new TextDecoder("utf-8").decode(new Uint8Array([0xff]));
 
-    assert_throws({name: 'EncodingError'}, function() { new TextDecoder("utf-16", {fatal: true}).decode(new Uint8Array([0x00])); });
+    assert_throws({name: 'TypeError'}, function() { new TextDecoder("utf-16", {fatal: true}).decode(new Uint8Array([0x00])); });
     // This should not hang:
     new TextDecoder("utf-16").decode(new Uint8Array([0x00]));
 
-    assert_throws({name: 'EncodingError'}, function() { new TextDecoder("utf-16be", {fatal: true}).decode(new Uint8Array([0x00])); });
+    assert_throws({name: 'TypeError'}, function() { new TextDecoder("utf-16be", {fatal: true}).decode(new Uint8Array([0x00])); });
     // This should not hang:
     new TextDecoder("utf-16be").decode(new Uint8Array([0x00]));
   },
   "Non-fatal errors at EOF"
 );
 
 test(
   function () {
@@ -210,13 +210,13 @@ test(
 
     utf_encodings.forEach(function(encoding) {
       assert_equals(new TextDecoder(encoding).encoding, encoding);
       assert_equals(new TextEncoder(encoding).encoding, encoding);
     });
 
     legacy_encodings.forEach(function(encoding) {
       assert_equals(new TextDecoder(encoding).encoding, encoding);
-      assert_throws({name: 'TypeError'}, function() { new TextEncoder(encoding); });
+      assert_throws({name: 'RangeError'}, function() { new TextEncoder(encoding); });
     });
   },
   "Non-UTF encodings supported only for decode, not encode"
 );
--- a/dom/fetch/Response.cpp
+++ b/dom/fetch/Response.cpp
@@ -90,17 +90,17 @@ Response::Redirect(const GlobalObject& a
     url->Stringify(parsedURL, aRv);
   }
 
   if (aRv.Failed()) {
     return nullptr;
   }
 
   if (aStatus != 301 && aStatus != 302 && aStatus != 303 && aStatus != 307 && aStatus != 308) {
-    aRv.Throw(NS_ERROR_RANGE_ERR);
+    aRv.ThrowRangeError(MSG_INVALID_REDIRECT_STATUSCODE_ERROR);
     return nullptr;
   }
 
   Optional<ArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams> body;
   ResponseInit init;
   init.mStatus = aStatus;
   nsRefPtr<Response> r = Response::Constructor(aGlobal, body, init, aRv);
   if (NS_WARN_IF(aRv.Failed())) {
@@ -117,17 +117,17 @@ Response::Redirect(const GlobalObject& a
 }
 
 /*static*/ already_AddRefed<Response>
 Response::Constructor(const GlobalObject& aGlobal,
                       const Optional<ArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams>& aBody,
                       const ResponseInit& aInit, ErrorResult& aRv)
 {
   if (aInit.mStatus < 200 || aInit.mStatus > 599) {
-    aRv.Throw(NS_ERROR_RANGE_ERR);
+    aRv.ThrowRangeError(MSG_INVALID_RESPONSE_STATUSCODE_ERROR);
     return nullptr;
   }
 
   nsCString statusText;
   if (aInit.mStatusText.WasPassed()) {
     statusText = aInit.mStatusText.Value();
     nsACString::const_iterator start, end;
     statusText.BeginReading(start);
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -3247,17 +3247,20 @@ void HTMLMediaElement::CheckProgress(boo
       if (!mLoadedDataFired) {
         ChangeDelayLoadStatus(true);
       }
     }
   }
 
   if (now - mDataTime >= TimeDuration::FromMilliseconds(STALL_MS)) {
     DispatchAsyncEvent(NS_LITERAL_STRING("stalled"));
-    ChangeDelayLoadStatus(false);
+
+    if (IsMediaSourceURI(mLoadingSrc)) {
+      ChangeDelayLoadStatus(false);
+    }
 
     NS_ASSERTION(mProgressTimer, "detected stalled without timer");
     // Stop timer events, which prevents repeated stalled events until there
     // is more progress.
     StopProgress();
   }
 
   AddRemoveSelfReference();
--- a/dom/ipc/PPluginWidget.ipdl
+++ b/dom/ipc/PPluginWidget.ipdl
@@ -28,17 +28,18 @@ namespace plugins {
  */
 sync protocol PPluginWidget {
   manager PBrowser;
 
 parent:
   async __delete__();
 
 parent:
-  async Create();
+  sync Create() returns (nsresult aResult);
+
   async Destroy();
   async SetFocus(bool aRaise);
 
   /**
    * Returns NS_NATIVE_PLUGIN_PORT and its variants: a sharable native
    * window for plugins. On Linux, this returns an XID for a socket widget
    * embedded in the chrome side native window. On Windows this returns the
    * native HWND of the plugin widget.
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -1091,18 +1091,17 @@ TabChild::Init()
   mWidget = nsIWidget::CreatePuppetWidget(this);
   if (!mWidget) {
     NS_ERROR("couldn't create fake widget");
     return NS_ERROR_FAILURE;
   }
   mWidget->Create(
     nullptr, 0,              // no parents
     nsIntRect(nsIntPoint(0, 0), nsIntSize(0, 0)),
-    nullptr,                 // HandleWidgetEvent
-    nullptr                  // nsDeviceContext
+    nullptr                  // HandleWidgetEvent
   );
 
   baseWindow->InitWindow(0, mWidget, 0, 0, 0, 0);
   baseWindow->Create();
 
   NotifyTabContextUpdated();
 
   // IPC uses a WebBrowser object for which DNS prefetching is turned off
@@ -3476,42 +3475,44 @@ TabChild::AllocPPluginWidgetChild()
 
 bool
 TabChild::DeallocPPluginWidgetChild(mozilla::plugins::PPluginWidgetChild* aActor)
 {
     delete aActor;
     return true;
 }
 
-already_AddRefed<nsIWidget>
-TabChild::CreatePluginWidget(nsIWidget* aParent)
+nsresult
+TabChild::CreatePluginWidget(nsIWidget* aParent, nsIWidget** aOut)
 {
+  *aOut = nullptr;
   mozilla::plugins::PluginWidgetChild* child =
     static_cast<mozilla::plugins::PluginWidgetChild*>(SendPPluginWidgetConstructor());
   if (!child) {
     NS_ERROR("couldn't create PluginWidgetChild");
-    return nullptr;
+    return NS_ERROR_UNEXPECTED;
   }
   nsCOMPtr<nsIWidget> pluginWidget = nsIWidget::CreatePluginProxyWidget(this, child);
   if (!pluginWidget) {
     NS_ERROR("couldn't create PluginWidgetProxy");
-    return nullptr;
+    return NS_ERROR_UNEXPECTED;
   }
 
   nsWidgetInitData initData;
   initData.mWindowType = eWindowType_plugin_ipc_content;
   initData.mUnicode = false;
   initData.clipChildren = true;
   initData.clipSiblings = true;
   nsresult rv = pluginWidget->Create(aParent, nullptr, nsIntRect(nsIntPoint(0, 0),
-                                     nsIntSize(0, 0)), nullptr, &initData);
+                                     nsIntSize(0, 0)), &initData);
   if (NS_FAILED(rv)) {
     NS_WARNING("Creating native plugin widget on the chrome side failed.");
   }
-  return pluginWidget.forget();
+  pluginWidget.forget(aOut);
+  return rv;
 }
 
 TabChildGlobal::TabChildGlobal(TabChildBase* aTabChild)
 : mTabChild(aTabChild)
 {
   SetIsNotDOMBinding();
 }
 
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -489,17 +489,17 @@ public:
 
     virtual bool RecvUIResolutionChanged() MOZ_OVERRIDE;
 
     /**
      * Native widget remoting protocol for use with windowed plugins with e10s.
      */
     PPluginWidgetChild* AllocPPluginWidgetChild() MOZ_OVERRIDE;
     bool DeallocPPluginWidgetChild(PPluginWidgetChild* aActor) MOZ_OVERRIDE;
-    already_AddRefed<nsIWidget> CreatePluginWidget(nsIWidget* aParent);
+    nsresult CreatePluginWidget(nsIWidget* aParent, nsIWidget** aOut);
 
     nsIntPoint GetChromeDisplacement() { return mChromeDisp; };
 
     bool IPCOpen() { return mIPCOpen; }
 
 protected:
     virtual ~TabChild();
 
--- a/dom/media/eme/MediaKeyStatusMap.cpp
+++ b/dom/media/eme/MediaKeyStatusMap.cpp
@@ -42,20 +42,23 @@ MediaKeyStatusMap::MediaKeyStatusMap(JSC
                                      ErrorResult& aRv)
   : mParent(aParent)
   , mUpdateError(NS_OK)
 {
   mMap = JS::NewMapObject(aCx);
   if (NS_WARN_IF(!mMap)) {
     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
   }
+
+  mozilla::HoldJSObjects(this);
 }
 
 MediaKeyStatusMap::~MediaKeyStatusMap()
 {
+  mozilla::DropJSObjects(this);
 }
 
 JSObject*
 MediaKeyStatusMap::WrapObject(JSContext* aCx)
 {
   return MediaKeyStatusMapBinding::Wrap(aCx, this);
 }
 
--- a/dom/media/mediasource/test/mochitest.ini
+++ b/dom/media/mediasource/test/mochitest.ini
@@ -30,15 +30,14 @@ skip-if = (toolkit == 'android' || build
 [test_LoadedMetadataFired.html]
 [test_MediaSource.html]
 [test_MediaSource_disabled.html]
 [test_SeekableAfterEndOfStream.html]
 [test_SeekableAfterEndOfStreamSplit.html]
 [test_SeekableBeforeEndOfStream.html]
 [test_SeekableBeforeEndOfStreamSplit.html]
 [test_SeekTwice_mp4.html]
-#skip-if = os == 'linux' # No fmp4 support on linux
-skip-if = true # Fails on most platforms and was pushed anyway.
+skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
 [test_SetModeThrows.html]
 [test_SplitAppendDelay.html]
 [test_SplitAppend.html]
 [test_WaitingOnMissingData.html]
  skip-if = android_version == '10' # bug 1115148 - frequent failures on Android 2.3
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -2867,33 +2867,36 @@ NS_IMETHODIMP nsPluginInstanceOwner::Cre
         nsCOMPtr<nsIDOMWindow> window = doc->GetWindow();
         if (window) {
           nsCOMPtr<nsIDOMWindow> topWindow;
           window->GetTop(getter_AddRefs(topWindow));
           if (topWindow) {
             dom::TabChild* tc = dom::TabChild::GetFrom(topWindow);
             if (tc) {
               // This returns a PluginWidgetProxy which remotes a number of calls.
-              mWidget = tc->CreatePluginWidget(parentWidget.get());
+              rv = tc->CreatePluginWidget(parentWidget.get(), getter_AddRefs(mWidget));
+              if (NS_FAILED(rv)) {
+                return rv;
+              }
             }
           }
         }
       }
 #endif // XP_MACOSX
     }
     if (!mWidget) {
       // native (single process)
       mWidget = do_CreateInstance(kWidgetCID, &rv);
       nsWidgetInitData initData;
       initData.mWindowType = eWindowType_plugin;
       initData.mUnicode = false;
       initData.clipChildren = true;
       initData.clipSiblings = true;
       rv = mWidget->Create(parentWidget.get(), nullptr, nsIntRect(0,0,0,0),
-                           nullptr, &initData);
+                           &initData);
       if (NS_FAILED(rv)) {
         mWidget->Destroy();
         mWidget = nullptr;
         return rv;
       }
     }
 
 
--- a/dom/plugins/ipc/PluginModuleParent.cpp
+++ b/dom/plugins/ipc/PluginModuleParent.cpp
@@ -389,31 +389,31 @@ PluginModuleChromeParent::SendAssociateP
 
 // static
 PluginLibrary*
 PluginModuleChromeParent::LoadModule(const char* aFilePath, uint32_t aPluginId,
                                      nsPluginTag* aPluginTag)
 {
     PLUGIN_LOG_DEBUG_FUNCTION;
 
-    bool enableSandbox = false;
+    int32_t sandboxLevel = 0;
 #if defined(XP_WIN) && defined(MOZ_SANDBOX)
-    nsAutoCString sandboxPref("dom.ipc.plugins.sandbox.");
+    nsAutoCString sandboxPref("dom.ipc.plugins.sandbox-level.");
     sandboxPref.Append(aPluginTag->GetNiceFileName());
-    if (NS_FAILED(Preferences::GetBool(sandboxPref.get(), &enableSandbox))) {
-      enableSandbox = Preferences::GetBool("dom.ipc.plugins.sandbox.default");
+    if (NS_FAILED(Preferences::GetInt(sandboxPref.get(), &sandboxLevel))) {
+      sandboxLevel = Preferences::GetInt("dom.ipc.plugins.sandbox-level.default");
     }
 #endif
 
     nsAutoPtr<PluginModuleChromeParent> parent(new PluginModuleChromeParent(aFilePath, aPluginId));
     UniquePtr<LaunchCompleteTask> onLaunchedRunnable(new LaunchedTask(parent));
     parent->mSubprocess->SetCallRunnableImmediately(!parent->mIsStartingAsync);
     TimeStamp launchStart = TimeStamp::Now();
     bool launched = parent->mSubprocess->Launch(Move(onLaunchedRunnable),
-                                                enableSandbox);
+                                                sandboxLevel);
     if (!launched) {
         // We never reached open
         parent->mShutdown = true;
         return nullptr;
     }
     parent->mIsFlashPlugin = aPluginTag->mIsFlashPlugin;
     parent->mIsBlocklisted = aPluginTag->GetBlocklistState() != 0;
     if (!parent->mIsStartingAsync) {
--- a/dom/plugins/ipc/PluginProcessParent.cpp
+++ b/dom/plugins/ipc/PluginProcessParent.cpp
@@ -9,20 +9,16 @@
 #include "base/string_util.h"
 #include "base/process_util.h"
 
 #include "mozilla/ipc/BrowserProcessSubThread.h"
 #include "mozilla/plugins/PluginMessageUtils.h"
 #include "mozilla/Telemetry.h"
 #include "nsThreadUtils.h"
 
-#if defined(XP_WIN) && defined(MOZ_SANDBOX)
-#include "mozilla/Preferences.h"
-#endif
-
 using std::vector;
 using std::string;
 
 using mozilla::ipc::BrowserProcessSubThread;
 using mozilla::ipc::GeckoChildProcessHost;
 using mozilla::plugins::LaunchCompleteTask;
 using mozilla::plugins::PluginProcessParent;
 using base::ProcessArchitecture;
@@ -43,24 +39,22 @@ PluginProcessParent::PluginProcessParent
 }
 
 PluginProcessParent::~PluginProcessParent()
 {
 }
 
 bool
 PluginProcessParent::Launch(mozilla::UniquePtr<LaunchCompleteTask> aLaunchCompleteTask,
-                            bool aEnableSandbox)
+                            int32_t aSandboxLevel)
 {
 #if defined(XP_WIN) && defined(MOZ_SANDBOX)
-    mEnableNPAPISandbox = aEnableSandbox;
-    mMoreStrictSandbox =
-      Preferences::GetBool("dom.ipc.plugins.moreStrictSandbox");
+    mSandboxLevel = aSandboxLevel;
 #else
-    if (aEnableSandbox) {
+    if (aSandboxLevel != 0) {
         MOZ_ASSERT(false,
                    "Can't enable an NPAPI process sandbox for platform/build.");
     }
 #endif
 
     ProcessArchitecture currentArchitecture = base::GetCurrentProcessArchitecture();
     uint32_t containerArchitectures = GetSupportedArchitecturesForProcessType(GeckoProcessType_Plugin);
 
--- a/dom/plugins/ipc/PluginProcessParent.h
+++ b/dom/plugins/ipc/PluginProcessParent.h
@@ -45,21 +45,21 @@ public:
     ~PluginProcessParent();
 
     /**
      * Launch the plugin process. If the process fails to launch,
      * this method will return false.
      *
      * @param aLaunchCompleteTask Task that is executed on the main
      * thread once the asynchonous launch has completed.
-     * @param aEnableSandbox Enables a process sandbox if one is available for
-     * this platform/build. Will assert if true passed and one is not available.
+     * @param aSandboxLevel Determines the strength of the sandbox.
+     * <= 0 means no sandbox.
      */
     bool Launch(UniquePtr<LaunchCompleteTask> aLaunchCompleteTask = UniquePtr<LaunchCompleteTask>(),
-                bool aEnableSandbox = false);
+                int32_t aSandboxLevel = 0);
 
     void Delete();
 
     virtual bool CanShutdown() MOZ_OVERRIDE
     {
         return true;
     }
 
--- a/dom/plugins/ipc/PluginWidgetParent.cpp
+++ b/dom/plugins/ipc/PluginWidgetParent.cpp
@@ -1,14 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "PluginWidgetParent.h"
 #include "mozilla/dom/TabParent.h"
+#include "mozilla/dom/ContentParent.h"
 #include "nsComponentManagerUtils.h"
 #include "nsWidgetsCID.h"
 #include "mozilla/DebugOnly.h"
 #include "nsDebug.h"
 #include "mozilla/unused.h"
 
 #if defined(MOZ_WIDGET_GTK)
 #include "nsPluginNativeWindowGtk.h"
@@ -94,50 +95,54 @@ PluginWidgetParent::SendAsyncUpdate(nsIW
 #endif // defined(XP_WIN)
 
 // When plugins run in chrome, nsPluginNativeWindow(Plat) implements platform
 // specific functionality that wraps plugin widgets. With e10s we currently
 // bypass this code on Window, and reuse a bit of it on Linux. Content still
 // makes use of some of the utility functions as well.
 
 bool
-PluginWidgetParent::RecvCreate()
+PluginWidgetParent::RecvCreate(nsresult* aResult)
 {
   PWLOG("PluginWidgetParent::RecvCreate()\n");
 
-  nsresult rv;
-
-  mWidget = do_CreateInstance(kWidgetCID, &rv);
-  NS_ASSERTION(NS_SUCCEEDED(rv), "widget create failure");
+  mWidget = do_CreateInstance(kWidgetCID, aResult);
+  NS_ASSERTION(NS_SUCCEEDED(*aResult), "widget create failure");
 
 #if defined(MOZ_WIDGET_GTK)
   // We need this currently just for GTK in setting up a socket widget
   // we can send over to content -> plugin.
   PLUG_NewPluginNativeWindow((nsPluginNativeWindow**)&mWrapper);
   if (!mWrapper) {
     return false;
   }
   // Give a copy of this to the widget, which handles some update
   // work for us.
   mWidget->SetNativeData(NS_NATIVE_PLUGIN_OBJECT_PTR, (uintptr_t)mWrapper.get());
 #endif
 
   // This returns the top level window widget
   nsCOMPtr<nsIWidget> parentWidget = GetTabParent()->GetWidget();
+  // If this fails, bail.
+  if (!parentWidget) {
+    *aResult = NS_ERROR_NOT_AVAILABLE;
+    return true;
+  }
 
   nsWidgetInitData initData;
   initData.mWindowType = eWindowType_plugin_ipc_chrome;
   initData.mUnicode = false;
   initData.clipChildren = true;
   initData.clipSiblings = true;
-  rv = mWidget->Create(parentWidget.get(), nullptr, nsIntRect(0,0,0,0),
-                       nullptr, &initData);
-  if (NS_FAILED(rv)) {
+  *aResult = mWidget->Create(parentWidget.get(), nullptr, nsIntRect(0,0,0,0),
+                             &initData);
+  if (NS_FAILED(*aResult)) {
     mWidget->Destroy();
     mWidget = nullptr;
+    // This should never fail, abort.
     return false;
   }
 
   DebugOnly<nsresult> drv;
   drv = mWidget->EnableDragDrop(true);
   NS_ASSERTION(NS_SUCCEEDED(drv), "widget call failure");
   drv = mWidget->Show(true);
   NS_ASSERTION(NS_SUCCEEDED(drv), "widget call failure");
--- a/dom/plugins/ipc/PluginWidgetParent.h
+++ b/dom/plugins/ipc/PluginWidgetParent.h
@@ -32,17 +32,17 @@ public:
    */
   static void SendAsyncUpdate(nsIWidget* aWidget);
 
 public:
   PluginWidgetParent();
   virtual ~PluginWidgetParent();
 
   virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
-  virtual bool RecvCreate() MOZ_OVERRIDE;
+  virtual bool RecvCreate(nsresult* aResult) MOZ_OVERRIDE;
   virtual bool RecvDestroy() MOZ_OVERRIDE;
   virtual bool RecvSetFocus(const bool& aRaise) MOZ_OVERRIDE;
   virtual bool RecvGetNativePluginPort(uintptr_t* value) MOZ_OVERRIDE;
 
   // Helper for compositor checks on the channel
   bool ActorDestroyed() { return mActorDestroyed; }
 
   // Called by PBrowser when it receives a Destroy() call from the child.
--- a/dom/settings/SettingsDB.jsm
+++ b/dom/settings/SettingsDB.jsm
@@ -75,17 +75,24 @@ SettingsDB.prototype = {
       // On b2g desktop builds the settings.json file is moved in the
       // profile directory by the build system.
       settingsFile = FileUtils.getFile("ProfD", ["settings.json"], false);
       if (!settingsFile || (settingsFile && !settingsFile.exists())) {
         return;
       }
     }
 
-    let chan = NetUtil.newChannel(settingsFile);
+    let chan = NetUtil.newChannel2(settingsFile,
+                                   null,
+                                   null,
+                                   null,      // aLoadingNode
+                                   Services.scriptSecurityManager.getSystemPrincipal(),
+                                   null,      // aTriggeringPrincipal
+                                   Ci.nsILoadInfo.SEC_NORMAL,
+                                   Ci.nsIContentPolicy.TYPE_OTHER);
     let stream = chan.open();
     // Obtain a converter to read from a UTF-8 encoded input stream.
     let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
                     .createInstance(Ci.nsIScriptableUnicodeConverter);
     converter.charset = "UTF-8";
     let rawstr = converter.ConvertToUnicode(NetUtil.readInputStreamToString(
                                             stream,
                                             stream.available()) || "");
--- a/dom/svg/SVGSVGElement.cpp
+++ b/dom/svg/SVGSVGElement.cpp
@@ -466,17 +466,17 @@ void
 SVGSVGElement::SetZoomAndPan(uint16_t aZoomAndPan, ErrorResult& rv)
 {
   if (aZoomAndPan == SVG_ZOOMANDPAN_DISABLE ||
       aZoomAndPan == SVG_ZOOMANDPAN_MAGNIFY) {
     mEnumAttributes[ZOOMANDPAN].SetBaseValue(aZoomAndPan, this);
     return;
   }
 
-  rv.Throw(NS_ERROR_RANGE_ERR);
+  rv.ThrowRangeError(MSG_INVALID_ZOOMANDPAN_VALUE_ERROR, &aZoomAndPan);
 }
 
 //----------------------------------------------------------------------
 // helper methods for implementing SVGZoomEvent:
 
 void
 SVGSVGElement::SetCurrentScaleTranslate(float s, float x, float y)
 {
--- a/dom/svg/SVGTransform.cpp
+++ b/dom/svg/SVGTransform.cpp
@@ -255,17 +255,17 @@ SVGTransform::SetSkewX(float angle, Erro
   }
 
   if (Transform().Type() == SVG_TRANSFORM_SKEWX &&
       Transform().Angle() == angle) {
     return;
   }
 
   if (!IsFinite(tan(angle * kRadPerDegree))) {
-    rv.Throw(NS_ERROR_RANGE_ERR);
+    rv.ThrowRangeError(MSG_INVALID_TRANSFORM_ANGLE_ERROR);
     return;
   }
 
   AutoChangeTransformNotifier notifier(this);
   DebugOnly<nsresult> result = Transform().SetSkewX(angle);
   MOZ_ASSERT(NS_SUCCEEDED(result), "SetSkewX unexpectedly failed");
 }
 
@@ -278,17 +278,17 @@ SVGTransform::SetSkewY(float angle, Erro
   }
 
   if (Transform().Type() == SVG_TRANSFORM_SKEWY &&
       Transform().Angle() == angle) {
     return;
   }
 
   if (!IsFinite(tan(angle * kRadPerDegree))) {
-    rv.Throw(NS_ERROR_RANGE_ERR);
+    rv.ThrowRangeError(MSG_INVALID_TRANSFORM_ANGLE_ERROR);
     return;
   }
 
   AutoChangeTransformNotifier notifier(this);
   DebugOnly<nsresult> result = Transform().SetSkewY(angle);
   MOZ_ASSERT(NS_SUCCEEDED(result), "SetSkewY unexpectedly failed");
 }
 
--- a/dom/svg/SVGViewElement.cpp
+++ b/dom/svg/SVGViewElement.cpp
@@ -54,17 +54,17 @@ void
 SVGViewElement::SetZoomAndPan(uint16_t aZoomAndPan, ErrorResult& rv)
 {
   if (aZoomAndPan == SVG_ZOOMANDPAN_DISABLE ||
       aZoomAndPan == SVG_ZOOMANDPAN_MAGNIFY) {
     mEnumAttributes[ZOOMANDPAN].SetBaseValue(aZoomAndPan, this);
     return;
   }
 
-  rv.Throw(NS_ERROR_RANGE_ERR);
+  rv.ThrowRangeError(MSG_INVALID_ZOOMANDPAN_VALUE_ERROR);
 }
 
 //----------------------------------------------------------------------
 
 already_AddRefed<SVGAnimatedRect>
 SVGViewElement::ViewBox()
 {
   return mViewBox.ToSVGAnimatedRect(this);
--- a/dom/system/gonk/NetworkService.js
+++ b/dom/system/gonk/NetworkService.js
@@ -126,17 +126,17 @@ NetworkService.prototype = {
     if(DEBUG) debug("getNetworkInterfaceStats for " + networkName);
 
     let file = new FileUtils.File("/proc/net/dev");
     if (!file) {
       callback.networkStatsAvailable(false, 0, 0, Date.now());
       return;
     }
 
-    NetUtil.asyncFetch(file, function(inputStream, status) {
+    NetUtil.asyncFetch2(file, function(inputStream, status) {
       let rxBytes = 0,
           txBytes = 0,
           now = Date.now();
 
       if (Components.isSuccessCode(status)) {
         // Find record for corresponding interface.
         let statExpr = /(\S+): +(\d+) +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +(\d+) +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+/;
         let data =
@@ -149,17 +149,22 @@ NetworkService.prototype = {
             txBytes = parseInt(parseResult[3], 10);
             break;
           }
         }
       }
 
       // netd always return success even interface doesn't exist.
       callback.networkStatsAvailable(true, rxBytes, txBytes, now);
-    });
+    },
+    null,      // aLoadingNode
+    Services.scriptSecurityManager.getSystemPrincipal(),
+    null,      // aTriggeringPrincipal
+    Ci.nsILoadInfo.SEC_NORMAL,
+    Ci.nsIContentPolicy.TYPE_OTHER);
   },
 
   setNetworkInterfaceAlarm: function(networkName, threshold, callback) {
     if (!networkName) {
       callback.networkUsageAlarmResult(-1);
       return;
     }
 
--- a/dom/system/mac/CoreLocationLocationProvider.mm
+++ b/dom/system/mac/CoreLocationLocationProvider.mm
@@ -53,24 +53,23 @@ static const CLLocationAccuracy kDEFAULT
 
 - (void)shutdownHandoffTimer
 {
   if (!mHandoffTimer) {
     return;
   }
 
   [mHandoffTimer invalidate];
+  [mHandoffTimer release];
   mHandoffTimer = nil;
 }
 
 - (void)handoffToGeoIPProvider
 {
-  // Single-shot timers are invalid once executed and are released by the run loop
-  mHandoffTimer = nil;
-
+  [self shutdownHandoffTimer];
   mProvider->CreateMLSFallbackProvider();
 }
 
 - (void)locationManager:(CLLocationManager*)aManager
   didFailWithError:(NSError *)aError
 {
   nsCOMPtr<nsIConsoleService> console =
     do_GetService(NS_CONSOLESERVICE_CONTRACTID);
@@ -91,21 +90,21 @@ static const CLLocationAccuracy kDEFAULT
     // The CL provider does not fallback to GeoIP, so use NetworkGeolocationProvider for this.
     // The concept here is: on error, hand off geolocation to MLS, which will then report
     // back a location or error. We can't call this with no delay however, as this method
     // is called with an error code of 0 in both failed geolocation cases, and also when
     // geolocation is not immediately available.
     // The 2 sec delay is arbitrarily large enough that CL has a reasonable head start and
     // if it is likely to succeed, it should complete before the MLS provider.
     // Take note that in locationManager:didUpdateLocations: the handoff to MLS is stopped.
-    mHandoffTimer = [NSTimer scheduledTimerWithTimeInterval:2.0
+    mHandoffTimer = [[NSTimer scheduledTimerWithTimeInterval:2.0
                                                      target:self
                                                    selector:@selector(handoffToGeoIPProvider)
                                                    userInfo:nil
-                                                    repeats:NO];
+                                                    repeats:NO] retain];
   }
 }
 
 - (void)locationManager:(CLLocationManager*)aManager didUpdateLocations:(NSArray*)aLocations
 {
   if (aLocations.count < 1) {
     return;
   }
--- a/embedding/browser/nsWebBrowser.cpp
+++ b/embedding/browser/nsWebBrowser.cpp
@@ -1107,17 +1107,17 @@ NS_IMETHODIMP nsWebBrowser::Create()
     nsWidgetInitData  widgetInit;
 
     widgetInit.clipChildren = true;
 
     widgetInit.mWindowType = eWindowType_child;
     nsIntRect bounds(mInitInfo->x, mInitInfo->y, mInitInfo->cx, mInitInfo->cy);
 
     mInternalWidget->SetWidgetListener(this);
-    mInternalWidget->Create(nullptr, mParentNativeWindow, bounds, nullptr, &widgetInit);
+    mInternalWidget->Create(nullptr, mParentNativeWindow, bounds, &widgetInit);
   }
 
   nsCOMPtr<nsIDocShell> docShell(do_CreateInstance("@mozilla.org/docshell;1", &rv));
   NS_ENSURE_SUCCESS(rv, rv);
   rv = SetDocShell(docShell);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // get the system default window background colour
--- a/gfx/angle/BUILD.gn
+++ b/gfx/angle/BUILD.gn
@@ -159,16 +159,19 @@ if (is_win) {
       "ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ " +
         "\"d3dcompiler_46.dll\", \"d3dcompiler_43.dll\" }",
       "GL_APICALL=",
       "GL_GLEXT_PROTOTYPES=",
       "EGLAPI=",
     ]
     libs = []
 
+    # Windows-specific sources.
+    sources += rebase_path(gles_gypi.angle_libangle_win_sources, ".", "src")
+
     # Shared D3dD sources.
     if (angle_enable_d3d9 || angle_enable_d3d11) {
       sources += rebase_path(gles_gypi.angle_d3d_shared_sources, ".", "src")
     }
 
     if (angle_enable_d3d9) {
       sources += rebase_path(gles_gypi.angle_d3d9_sources, ".", "src")
       defines += [ "ANGLE_ENABLE_D3D9" ]
@@ -213,17 +216,20 @@ if (is_win) {
 
     configs -= [ "//build/config/compiler:chromium_code" ]
     configs += [
       ":internal_config",
       "//build/config/compiler:no_chromium_code",
     ]
 
     if (is_debug) {
-      defines += [ "ANGLE_ENABLE_PERF" ]
+      defines += [
+        "ANGLE_ENABLE_PERF",
+        "ANGLE_GENERATE_SHADER_DEBUG_INFO"
+      ]
     }
 
     include_dirs = [ "src/libGLESv2" ]
     libs = [ "d3d9.lib" ]
 
     deps = [
       ":commit_id",
       ":includes",
--- a/gfx/angle/include/EGL/eglplatform.h
+++ b/gfx/angle/include/EGL/eglplatform.h
@@ -70,17 +70,23 @@
 #if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
 #ifndef WIN32_LEAN_AND_MEAN
 #define WIN32_LEAN_AND_MEAN 1
 #endif
 #include <windows.h>
 
 typedef HDC     EGLNativeDisplayType;
 typedef HBITMAP EGLNativePixmapType;
+
+#if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP /* Windows Store */
+#include <inspectable.h>
+typedef IInspectable* EGLNativeWindowType;
+#else
 typedef HWND    EGLNativeWindowType;
+#endif
 
 #elif defined(__WINSCW__) || defined(__SYMBIAN32__)  /* Symbian */
 
 typedef int   EGLNativeDisplayType;
 typedef void *EGLNativeWindowType;
 typedef void *EGLNativePixmapType;
 
 #elif defined(__ANDROID__) || defined(ANDROID)
--- a/gfx/angle/include/GLSLANG/ShaderLang.h
+++ b/gfx/angle/include/GLSLANG/ShaderLang.h
@@ -22,43 +22,46 @@
 #else  // defined(COMPONENT_BUILD) && !defined(ANGLE_TRANSLATOR_STATIC)
 #define COMPILER_EXPORT
 #endif
 
 #include <stddef.h>
 
 #include "KHR/khrplatform.h"
 
+#include <map>
+#include <string>
+#include <vector>
+
 //
 // This is the platform independent interface between an OGL driver
 // and the shading language compiler.
 //
 
 namespace sh
 {
 // GLenum alias
 typedef unsigned int GLenum;
 }
 
 // Must be included after GLenum proxy typedef
 // Note: make sure to increment ANGLE_SH_VERSION when changing ShaderVars.h
 #include "ShaderVars.h"
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 // Version number for shader translation API.
 // It is incremented every time the API changes.
-#define ANGLE_SH_VERSION 130
+#define ANGLE_SH_VERSION 132
 
 typedef enum {
   SH_GLES2_SPEC = 0x8B40,
   SH_WEBGL_SPEC = 0x8B41,
 
+  SH_GLES3_SPEC = 0x8B86,
+  SH_WEBGL2_SPEC = 0x8B87,
+
   // The CSS Shaders spec is a subset of the WebGL spec.
   //
   // In both CSS vertex and fragment shaders, ANGLE:
   // (1) Reserves the "css_" prefix.
   // (2) Renames the main function to css_main.
   // (3) Disables the gl_MaxDrawBuffers built-in.
   //
   // In CSS fragment shaders, ANGLE:
@@ -80,41 +83,16 @@ typedef enum {
 typedef enum {
   SH_ESSL_OUTPUT   = 0x8B45,
   SH_GLSL_OUTPUT   = 0x8B46,
   SH_HLSL_OUTPUT   = 0x8B47,
   SH_HLSL9_OUTPUT  = 0x8B47,
   SH_HLSL11_OUTPUT = 0x8B48
 } ShShaderOutput;
 
-typedef enum {
-  SH_PRECISION_HIGHP     = 0x5001,
-  SH_PRECISION_MEDIUMP   = 0x5002,
-  SH_PRECISION_LOWP      = 0x5003,
-  SH_PRECISION_UNDEFINED = 0
-} ShPrecisionType;
-
-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_VARYINGS                       = 0x8BBB,
-  SH_VARYING_MAX_LENGTH             = 0x8BBC,
-  SH_MAPPED_NAME_MAX_LENGTH         = 0x6000,
-  SH_NAME_MAX_LENGTH                = 0x6001,
-  SH_HASHED_NAME_MAX_LENGTH         = 0x6002,
-  SH_HASHED_NAMES_COUNT             = 0x6003,
-  SH_SHADER_VERSION                 = 0x6004,
-  SH_RESOURCES_STRING_LENGTH        = 0x6005,
-  SH_OUTPUT_TYPE                    = 0x6006
-} ShShaderInfo;
-
 // Compile options.
 typedef enum {
   SH_VALIDATE                = 0,
   SH_VALIDATE_LOOP_INDEXING  = 0x0001,
   SH_INTERMEDIATE_TREE       = 0x0002,
   SH_OBJECT_CODE             = 0x0004,
   SH_VARIABLES               = 0x0008,
   SH_LINE_DIRECTIVES         = 0x0010,
@@ -203,24 +181,24 @@ typedef enum {
 
   // Use a user-defined function for array index clamping.
   SH_CLAMP_WITH_USER_DEFINED_INT_CLAMP_FUNCTION
 } ShArrayIndexClampingStrategy;
 
 //
 // Driver must call this first, once, before doing any other
 // compiler operations.
-// If the function succeeds, the return value is nonzero, else zero.
+// If the function succeeds, the return value is true, else false.
 //
-COMPILER_EXPORT int ShInitialize();
+COMPILER_EXPORT bool ShInitialize();
 //
 // Driver should call this at shutdown.
-// If the function succeeds, the return value is nonzero, else zero.
+// If the function succeeds, the return value is true, else false.
 //
-COMPILER_EXPORT int ShFinalize();
+COMPILER_EXPORT bool ShFinalize();
 
 // The 64 bits hash function. The first parameter is the input string; the
 // second parameter is the string length.
 typedef khronos_uint64_t (*ShHashFunction64)(const char*, size_t);
 
 //
 // Implementation dependent built-in resources (constants and extensions).
 // The names for these resources has been obtained by stripping gl_/GL_.
@@ -275,38 +253,37 @@ typedef struct
     int MaxExpressionComplexity;
 
     // The maximum depth a call stack can be.
     int MaxCallStackDepth;
 } ShBuiltInResources;
 
 //
 // Initialize built-in resources with minimum expected values.
+// Parameters:
+// resources: The object to initialize. Will be comparable with memcmp.
 //
-COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources* resources);
+COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources *resources);
 
 //
 // ShHandle held by but opaque to the driver.  It is allocated,
 // managed, and de-allocated by the compiler. Its contents
 // are defined by and used by the compiler.
 //
 // If handle creation fails, 0 will be returned.
 //
-typedef void* ShHandle;
+typedef void *ShHandle;
 
 //
-// Returns the a concatenated list of the items in ShBuiltInResources as a string.
+// Returns the a concatenated list of the items in ShBuiltInResources as a
+// null-terminated string.
 // This function must be updated whenever ShBuiltInResources is changed.
 // Parameters:
 // handle: Specifies the handle of the compiler to be used.
-// outStringLen: Specifies the size of the buffer, in number of characters. The size
-//               of the buffer required to store the resources string can be obtained
-//               by calling ShGetInfo with SH_RESOURCES_STRING_LENGTH.
-// outStr: Returns a null-terminated string representing all the built-in resources.
-COMPILER_EXPORT void ShGetBuiltInResourcesString(const ShHandle handle, size_t outStringLen, char *outStr);
+COMPILER_EXPORT const std::string &ShGetBuiltInResourcesString(const ShHandle handle);
 
 //
 // Driver calls these to create and destroy compiler objects.
 //
 // Returns the handle of constructed compiler, null if the requested compiler is
 // not supported.
 // Parameters:
 // type: Specifies the type of shader - GL_FRAGMENT_SHADER or GL_VERTEX_SHADER.
@@ -314,22 +291,22 @@ COMPILER_EXPORT void ShGetBuiltInResourc
 //       SH_GLES2_SPEC or SH_WEBGL_SPEC.
 // output: Specifies the output code type - SH_ESSL_OUTPUT, SH_GLSL_OUTPUT,
 //         SH_HLSL9_OUTPUT or SH_HLSL11_OUTPUT.
 // resources: Specifies the built-in resources.
 COMPILER_EXPORT ShHandle ShConstructCompiler(
     sh::GLenum type,
     ShShaderSpec spec,
     ShShaderOutput output,
-    const ShBuiltInResources* resources);
+    const ShBuiltInResources *resources);
 COMPILER_EXPORT void ShDestruct(ShHandle handle);
 
 //
 // Compiles the given shader source.
-// If the function succeeds, the return value is nonzero, else zero.
+// If the function succeeds, the return value is true, else false.
 // Parameters:
 // handle: Specifies the handle of compiler to be used.
 // shaderStrings: Specifies an array of pointers to null-terminated strings
 //                containing the shader source code.
 // numStrings: Specifies the number of elements in shaderStrings array.
 // compileOptions: A mask containing the following parameters:
 // SH_VALIDATE: Validates shader to ensure that it conforms to the spec
 //              specified during compiler construction.
@@ -341,133 +318,46 @@ COMPILER_EXPORT void ShDestruct(ShHandle
 //                            compiling for WebGL - it is implied.
 // SH_INTERMEDIATE_TREE: Writes intermediate tree to info log.
 //                       Can be queried by calling ShGetInfoLog().
 // SH_OBJECT_CODE: Translates intermediate tree to glsl or hlsl shader.
 //                 Can be queried by calling ShGetObjectCode().
 // SH_VARIABLES: Extracts attributes, uniforms, and varyings.
 //               Can be queried by calling ShGetVariableInfo().
 //
-COMPILER_EXPORT int ShCompile(
+COMPILER_EXPORT bool ShCompile(
     const ShHandle handle,
-    const char* const shaderStrings[],
+    const char * const shaderStrings[],
     size_t numStrings,
-    int compileOptions
-    );
+    int compileOptions);
+
+// Return the version of the shader language.
+COMPILER_EXPORT int ShGetShaderVersion(const ShHandle handle);
 
-// Returns a parameter from a compiled shader.
+// Return the currently set language output type.
+COMPILER_EXPORT ShShaderOutput ShGetShaderOutputType(
+    const ShHandle handle);
+
+// Returns null-terminated information log for a compiled shader.
 // Parameters:
 // handle: Specifies the compiler
-// pname: Specifies the parameter to query.
-// The following parameters are defined:
-// SH_INFO_LOG_LENGTH: the number of characters in the information log
-//                     including the null termination character.
-// SH_OBJECT_CODE_LENGTH: the number of characters in the object code
-//                        including the null termination character.
-// 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_VARYINGS: the number of varying variables.
-// SH_VARYING_MAX_LENGTH: the length of the longest varying variable name
-//                        including the null termination character.
-// SH_MAPPED_NAME_MAX_LENGTH: the length of the mapped variable name including
-//                            the null termination character.
-// SH_NAME_MAX_LENGTH: the max length of a user-defined name including the
-//                     null termination character.
-// SH_HASHED_NAME_MAX_LENGTH: the max length of a hashed name including the
-//                            null termination character.
-// SH_HASHED_NAMES_COUNT: the number of hashed names from the latest compile.
-// SH_SHADER_VERSION: the version of the shader language
-// SH_OUTPUT_TYPE: the currently set language output type
-//
-// params: Requested parameter
-COMPILER_EXPORT void ShGetInfo(const ShHandle handle,
-                               ShShaderInfo pname,
-                               size_t* 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
-//          the information log. It is assumed that infoLog has enough memory
-//          to accomodate the information log. The size of the buffer required
-//          to store the returned information log can be obtained by calling
-//          ShGetInfo with SH_INFO_LOG_LENGTH.
-COMPILER_EXPORT void ShGetInfoLog(const ShHandle handle, char* infoLog);
+COMPILER_EXPORT const std::string &ShGetInfoLog(const ShHandle handle);
 
 // Returns null-terminated object code for a compiled shader.
 // Parameters:
 // handle: Specifies the compiler
-// infoLog: Specifies an array of characters that is used to return
-//          the object code. It is assumed that infoLog has enough memory to
-//          accomodate the object code. The size of the buffer required to
-//          store the returned object code can be obtained by calling
-//          ShGetInfo with SH_OBJECT_CODE_LENGTH.
-COMPILER_EXPORT void ShGetObjectCode(const ShHandle handle, char* objCode);
+COMPILER_EXPORT const std::string &ShGetObjectCode(const ShHandle handle);
 
-// Returns information about a shader variable.
+// Returns a (original_name, hash) map containing all the user defined
+// names in the shader, including variable names, function names, struct
+// names, and struct field names.
 // Parameters:
 // handle: Specifies the compiler
-// variableType: Specifies the variable type; options include
-//               SH_ACTIVE_ATTRIBUTES, SH_ACTIVE_UNIFORMS, SH_VARYINGS.
-// index: Specifies the index of the 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 variable.
-// type: Returns the data type of the variable.
-// precision: Returns the precision of the variable.
-// staticUse: Returns 1 if the variable is accessed in a statement after
-//            pre-processing, whether or not run-time flow of control will
-//            cause that statement to be executed.
-//            Returns 0 otherwise.
-// name: Returns a null terminated string containing the name of the
-//       variable. It is assumed that name has enough memory to accormodate
-//       the variable name. The size of the buffer required to store the
-//       variable name can be obtained by calling ShGetInfo with
-//       SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, SH_ACTIVE_UNIFORM_MAX_LENGTH,
-//       SH_VARYING_MAX_LENGTH.
-// mappedName: Returns a null terminated string containing the mapped name of
-//             the 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.
-COMPILER_EXPORT void ShGetVariableInfo(const ShHandle handle,
-                                       ShShaderInfo variableType,
-                                       int index,
-                                       size_t* length,
-                                       int* size,
-                                       sh::GLenum* type,
-                                       ShPrecisionType* precision,
-                                       int* staticUse,
-                                       char* name,
-                                       char* mappedName);
-
-// Returns information about a name hashing entry from the latest compile.
-// Parameters:
-// handle: Specifies the compiler
-// index: Specifies the index of the name hashing entry to be queried.
-// name: Returns a null terminated string containing the user defined name.
-//       It is assumed that name has enough memory to accomodate the name.
-//       The size of the buffer required to store the user defined name can
-//       be obtained by calling ShGetInfo with SH_NAME_MAX_LENGTH.
-// hashedName: Returns a null terminated string containing the hashed name of
-//             the uniform variable, It is assumed that hashedName has enough
-//             memory to accomodate the name. The size of the buffer required
-//             to store the name can be obtained by calling ShGetInfo with
-//             SH_HASHED_NAME_MAX_LENGTH.
-COMPILER_EXPORT void ShGetNameHashingEntry(const ShHandle handle,
-                                           int index,
-                                           char* name,
-                                           char* hashedName);
+COMPILER_EXPORT const std::map<std::string, std::string> *ShGetNameHashingMap(
+    const ShHandle handle);
 
 // Shader variable inspection.
 // Returns a pointer to a list of variables of the designated type.
 // (See ShaderVars.h for type definitions, included above)
 // Returns NULL on failure.
 // Parameters:
 // handle: Specifies the compiler
 COMPILER_EXPORT const std::vector<sh::Uniform> *ShGetUniforms(const ShHandle handle);
@@ -477,49 +367,45 @@ COMPILER_EXPORT const std::vector<sh::At
 COMPILER_EXPORT const std::vector<sh::InterfaceBlock> *ShGetInterfaceBlocks(const ShHandle handle);
 
 typedef struct
 {
     sh::GLenum type;
     int size;
 } ShVariableInfo;
 
-// Returns 1 if the passed in variables pack in maxVectors following
+// Returns true if the passed in variables pack in maxVectors following
 // the packing rules from the GLSL 1.017 spec, Appendix A, section 7.
-// Returns 0 otherwise. Also look at the SH_ENFORCE_PACKING_RESTRICTIONS
+// Returns false otherwise. Also look at the SH_ENFORCE_PACKING_RESTRICTIONS
 // flag above.
 // Parameters:
 // maxVectors: the available rows of registers.
 // varInfoArray: an array of variable info (types and sizes).
 // varInfoArraySize: the size of the variable array.
-COMPILER_EXPORT int ShCheckVariablesWithinPackingLimits(
+COMPILER_EXPORT bool ShCheckVariablesWithinPackingLimits(
     int maxVectors,
-    ShVariableInfo* varInfoArray,
+    ShVariableInfo *varInfoArray,
     size_t varInfoArraySize);
 
 // Gives the compiler-assigned register for an interface block.
 // The method writes the value to the output variable "indexOut".
 // Returns true if it found a valid interface block, false otherwise.
 // Parameters:
 // handle: Specifies the compiler
 // interfaceBlockName: Specifies the interface block
 // indexOut: output variable that stores the assigned register
 COMPILER_EXPORT bool ShGetInterfaceBlockRegister(const ShHandle handle,
-                                                 const char *interfaceBlockName,
+                                                 const std::string &interfaceBlockName,
                                                  unsigned int *indexOut);
 
 // Gives the compiler-assigned register for uniforms in the default
 // interface block.
 // The method writes the value to the output variable "indexOut".
 // Returns true if it found a valid default uniform, false otherwise.
 // Parameters:
 // handle: Specifies the compiler
 // interfaceBlockName: Specifies the uniform
 // indexOut: output variable that stores the assigned register
 COMPILER_EXPORT bool ShGetUniformRegister(const ShHandle handle,
-                                          const char *uniformName,
+                                          const std::string &uniformName,
                                           unsigned int *indexOut);
 
-#ifdef __cplusplus
-}
-#endif
-
 #endif // _COMPILER_INTERFACE_INCLUDED_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/include/angle_windowsstore.h
@@ -0,0 +1,37 @@
+//
+// Copyright (c) 2014 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.
+//
+// angle_windowsstore.h:
+
+#ifndef ANGLE_WINDOWSSTORE_H_
+#define ANGLE_WINDOWSSTORE_H_
+
+// The following properties can be set on the CoreApplication to support additional
+// ANGLE configuration options.
+//
+// The Visual Studio sample templates provided with this version of ANGLE have examples
+// of how to set these property values.
+
+//
+// Property: EGLNativeWindowTypeProperty
+// Type: IInspectable
+// Description: Set this property to specify the window type to use for creating a surface.
+//              If this property is missing, surface creation will fail.
+//
+const wchar_t EGLNativeWindowTypeProperty[] = L"EGLNativeWindowTypeProperty";
+
+//
+// Property: EGLRenderSurfaceSizeProperty
+// Type: Size
+// Description: Set this property to specify a preferred size in pixels of the render surface.
+//              The render surface size width and height must be greater than 0.
+//              If this property is set, then the render surface size is fixed.
+//              If this property is missing, a default behavior will be provided.
+//              The default behavior uses the window size if a CoreWindow is specified or
+//              the size of the SwapChainPanel control if one is specified.
+//
+const wchar_t EGLRenderSurfaceSizeProperty[] = L"EGLRenderSurfaceSizeProperty";
+
+#endif // ANGLE_WINDOWSSTORE_H_
--- a/gfx/angle/src/angle.gypi
+++ b/gfx/angle/src/angle.gypi
@@ -8,37 +8,60 @@
         'angle_code': 1,
         'angle_post_build_script%': 0,
         'angle_gen_path': '<(SHARED_INTERMEDIATE_DIR)/angle',
         'angle_id_script_base': 'commit_id.py',
         'angle_id_script': '<(angle_gen_path)/<(angle_id_script_base)',
         'angle_id_header_base': 'commit.h',
         'angle_id_header': '<(angle_gen_path)/id/<(angle_id_header_base)',
         'angle_use_commit_id%': '<!(python <(angle_id_script_base) check ..)',
+        'angle_enable_d3d9%': 0,
+        'angle_enable_d3d11%': 0,
+        'conditions':
+        [
+            ['OS=="win"',
+            {
+                'angle_enable_d3d9%': 1,
+                'angle_enable_d3d11%': 1,
+            }],
+        ],
     },
     'includes':
     [
         'compiler.gypi',
         'libGLESv2.gypi',
         'libEGL.gypi'
     ],
 
     'targets':
     [
         {
             'target_name': 'copy_scripts',
             'type': 'none',
+            'includes': [ '../build/common_defines.gypi', ],
             'hard_dependency': 1,
             'copies':
             [
                 {
                     'destination': '<(angle_gen_path)',
                     'files': [ 'copy_compiler_dll.bat', '<(angle_id_script_base)' ],
                 },
             ],
+            'conditions':
+            [
+                ['angle_build_winrt==1',
+                {
+                    'msvs_enable_winrt' : '1',
+                    'type' : 'shared_library',
+                }],
+                ['angle_build_winphone==1',
+                {
+                    'msvs_enable_winphone' : '1',
+                }],
+            ],
         },
     ],
     'conditions':
     [
         ['angle_use_commit_id!=0',
         {
             'targets':
             [
@@ -65,69 +88,109 @@
                     ],
                     'all_dependent_settings':
                     {
                         'include_dirs':
                         [
                             '<(angle_gen_path)',
                         ],
                     },
+                    'conditions':
+                    [
+                        ['angle_build_winrt==1',
+                        {
+                            'msvs_enable_winrt' : '1',
+                            'type' : 'shared_library',
+                        }],
+                        ['angle_build_winphone==1',
+                        {
+                            'msvs_enable_winphone' : '1',
+                        }],
+                    ],
                 }
             ]
         },
         { # angle_use_commit_id==0
             'targets':
             [
                 {
                     'target_name': 'commit_id',
                     'type': 'none',
                     'hard_dependency': 1,
+                    'includes': [ '../build/common_defines.gypi', ],
                     'copies':
                     [
                         {
                             'destination': '<(angle_gen_path)/id',
                             'files': [ '<(angle_id_header_base)' ]
                         }
                     ],
                     'all_dependent_settings':
                     {
                         'include_dirs':
                         [
                             '<(angle_gen_path)',
                         ],
                     },
+                    'conditions':
+                    [
+                        ['angle_build_winrt==1',
+                        {
+                            'msvs_enable_winrt' : '1',
+                            'type' : 'shared_library',
+                        }],
+                        ['angle_build_winphone==1',
+                        {
+                            'msvs_enable_winphone' : '1',
+                        }],
+                    ],
                 }
             ]
         }],
         ['OS=="win"',
         {
             'targets':
             [
                 {
                     'target_name': 'copy_compiler_dll',
                     'type': 'none',
                     'dependencies': [ 'copy_scripts', ],
                     'includes': [ '../build/common_defines.gypi', ],
-                    'actions':
+                    'conditions':
                     [
+                        ['angle_build_winrt==0',
                         {
-                            'action_name': 'copy_dll',
-                            'message': 'Copying D3D Compiler DLL...',
-                            'msvs_cygwin_shell': 0,
-                            'inputs': [ 'copy_compiler_dll.bat' ],
-                            'outputs': [ '<(PRODUCT_DIR)/d3dcompiler_46.dll' ],
-                            'action':
+                            'actions':
                             [
-                                "<(angle_gen_path)/copy_compiler_dll.bat",
-                                "$(PlatformName)",
-                                "<(windows_sdk_path)",
-                                "<(PRODUCT_DIR)"
-                            ],
-                        },
-                    ], #actions
+                                {
+                                    'action_name': 'copy_dll',
+                                    'message': 'Copying D3D Compiler DLL...',
+                                    'msvs_cygwin_shell': 0,
+                                    'inputs': [ 'copy_compiler_dll.bat' ],
+                                    'outputs': [ '<(PRODUCT_DIR)/d3dcompiler_46.dll' ],
+                                    'action':
+                                    [
+                                        "<(angle_gen_path)/copy_compiler_dll.bat",
+                                        "$(PlatformName)",
+                                        "<(windows_sdk_path)",
+                                        "<(PRODUCT_DIR)"
+                                    ],
+                                },
+                            ], #actions
+                        }],
+                        ['angle_build_winrt==1',
+                        {
+                            'msvs_enable_winrt' : '1',
+                            'type' : 'shared_library',
+                        }],
+                        ['angle_build_winphone==1',
+                        {
+                            'msvs_enable_winphone' : '1',
+                        }],
+                    ]
                 },
             ], # targets
         }],
         ['angle_post_build_script!=0 and OS=="win"',
         {
             'targets':
             [
                 {
deleted file mode 100644
--- a/gfx/angle/src/build_angle.gyp
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (c) 2012 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.
-
-{
-    'includes':
-    [
-        'angle.gypi',
-    ],
-}
--- a/gfx/angle/src/commit.h
+++ b/gfx/angle/src/commit.h
@@ -1,3 +1,3 @@
-#define ANGLE_COMMIT_HASH "0fb6a60df77b"
+#define ANGLE_COMMIT_HASH "180bf375fb42"
 #define ANGLE_COMMIT_HASH_SIZE 12
-#define ANGLE_COMMIT_DATE "2014-11-28 13:56:37 -0500"
+#define ANGLE_COMMIT_DATE "2015-02-05 14:21:03 -0500"
--- a/gfx/angle/src/common/NativeWindow.h
+++ b/gfx/angle/src/common/NativeWindow.h
@@ -11,47 +11,65 @@
 
 #ifndef COMMON_NATIVEWINDOW_H_
 #define COMMON_NATIVEWINDOW_H_
 
 #include <EGL/eglplatform.h>
 #include "common/debug.h"
 #include "common/platform.h"
 
-#ifdef ANGLE_ENABLE_D3D11
 // DXGISwapChain and DXGIFactory are typedef'd to specific required
 // types. The HWND NativeWindow implementation requires IDXGISwapChain
 // and IDXGIFactory and the Windows Store NativeWindow
 // implementation requires IDXGISwapChain1 and IDXGIFactory2.
+#if defined(ANGLE_ENABLE_WINDOWS_STORE)
+typedef IDXGISwapChain1 DXGISwapChain;
+typedef IDXGIFactory2 DXGIFactory;
+
+#include <wrl.h>
+#include <wrl/wrappers/corewrappers.h>
+#include <windows.applicationmodel.core.h>
+#include <memory>
+
+class IInspectableNativeWindow;
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+
+#else
+#ifdef ANGLE_ENABLE_D3D11
 typedef IDXGISwapChain DXGISwapChain;
 typedef IDXGIFactory DXGIFactory;
 #endif
+#endif
 
 namespace rx
 {
 class NativeWindow
 {
-  public:
+public:
     explicit NativeWindow(EGLNativeWindowType window);
 
-    // The HWND NativeWindow implementation can benefit
-    // by having inline versions of these methods to
-    // reduce the calling overhead.
-    inline bool initialize() { return true; }
-    inline bool getClientRect(LPRECT rect) { return GetClientRect(mWindow, rect) == TRUE; }
-    inline bool isIconic() { return IsIconic(mWindow) == TRUE; }
+    bool initialize();
+    bool getClientRect(LPRECT rect);
+    bool isIconic();
 
 #ifdef ANGLE_ENABLE_D3D11
     HRESULT createSwapChain(ID3D11Device* device, DXGIFactory* factory,
                             DXGI_FORMAT format, UINT width, UINT height,
                             DXGISwapChain** swapChain);
 #endif
 
     inline EGLNativeWindowType getNativeWindow() const { return mWindow; }
 
-  private:
+private:
     EGLNativeWindowType mWindow;
+
+#if defined(ANGLE_ENABLE_WINDOWS_STORE)
+    std::shared_ptr<IInspectableNativeWindow> mImpl;
+#endif
+
 };
 }
 
 bool isValidEGLNativeWindowType(EGLNativeWindowType window);
 
 #endif // COMMON_NATIVEWINDOW_H_
--- a/gfx/angle/src/common/angleutils.cpp
+++ b/gfx/angle/src/common/angleutils.cpp
@@ -1,35 +1,41 @@
 //
 // Copyright (c) 2014 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 "common/angleutils.h"
-
+#include "debug.h"
 #include <stdio.h>
 #include <vector>
 
+size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char>& outBuffer)
+{
+    // Attempt to just print to the current buffer
+    int len = vsnprintf(&(outBuffer.front()), outBuffer.size(), fmt, vararg);
+    if (len < 0 || static_cast<size_t>(len) >= outBuffer.size())
+    {
+        // Buffer was not large enough, calculate the required size and resize the buffer
+        len = vsnprintf(NULL, 0, fmt, vararg);
+        outBuffer.resize(len + 1);
+
+        // Print again
+        len = vsnprintf(&(outBuffer.front()), outBuffer.size(), fmt, vararg);
+    }
+    ASSERT(len >= 0);
+    return static_cast<size_t>(len);
+}
+
 std::string FormatString(const char *fmt, va_list vararg)
 {
     static std::vector<char> buffer(512);
 
-    // Attempt to just print to the current buffer
-    int len = vsnprintf(&buffer[0], buffer.size(), fmt, vararg);
-    if (len < 0 || static_cast<size_t>(len) >= buffer.size())
-    {
-        // Buffer was not large enough, calculate the required size and resize the buffer
-        len = vsnprintf(NULL, 0, fmt, vararg);
-        buffer.resize(len + 1);
-
-        // Print again
-        vsnprintf(&buffer[0], buffer.size(), fmt, vararg);
-    }
-
+    size_t len = FormatStringIntoVector(fmt, vararg, buffer);
     return std::string(&buffer[0], len);
 }
 
 std::string FormatString(const char *fmt, ...)
 {
     va_list vararg;
     va_start(vararg, fmt);
     std::string result = FormatString(fmt, vararg);
--- a/gfx/angle/src/common/angleutils.h
+++ b/gfx/angle/src/common/angleutils.h
@@ -12,16 +12,17 @@
 #include "common/platform.h"
 
 #include <stddef.h>
 #include <limits.h>
 #include <string>
 #include <set>
 #include <sstream>
 #include <cstdarg>
+#include <vector>
 
 // A macro to disallow the copy constructor and operator= functions
 // This must be used in the private: declarations for a class
 #define DISALLOW_COPY_AND_ASSIGN(TypeName) \
   TypeName(const TypeName&);               \
   void operator=(const TypeName&)
 
 template <typename T, size_t N>
@@ -90,16 +91,23 @@ inline bool StructEquals(const T &a, con
 }
 
 template <typename T>
 inline void StructZero(T *obj)
 {
     memset(obj, 0, sizeof(T));
 }
 
+template <typename T>
+inline bool IsMaskFlagSet(T mask, T flag)
+{
+    // Handles multibit flags as well
+    return (mask & flag) == flag;
+}
+
 inline const char* MakeStaticString(const std::string &str)
 {
     static std::set<std::string> strings;
     std::set<std::string>::iterator it = strings.find(str);
     if (it != strings.end())
     {
         return it->c_str();
     }
@@ -127,16 +135,18 @@ inline std::string ArrayString(unsigned 
 
 inline std::string Str(int i)
 {
     std::stringstream strstr;
     strstr << i;
     return strstr.str();
 }
 
+size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char>& buffer);
+
 std::string FormatString(const char *fmt, va_list vararg);
 std::string FormatString(const char *fmt, ...);
 
 #if defined(_MSC_VER)
 #define snprintf _snprintf
 #endif
 
 #define VENDOR_ID_AMD 0x1002
--- a/gfx/angle/src/common/debug.cpp
+++ b/gfx/angle/src/common/debug.cpp
@@ -12,104 +12,278 @@
 
 #include <stdarg.h>
 #include <vector>
 #include <fstream>
 #include <cstdio>
 
 namespace gl
 {
-#if defined(ANGLE_ENABLE_PERF)
-typedef void (WINAPI *PerfOutputFunction)(D3DCOLOR, LPCWSTR);
-#else
-typedef void (*PerfOutputFunction)(unsigned int, const wchar_t*);
+#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
+// Wraps the D3D9/D3D11 debug annotation functions.
+class DebugAnnotationWrapper
+{
+  public:
+    DebugAnnotationWrapper() { };
+    virtual ~DebugAnnotationWrapper() { };
+    virtual void beginEvent(const std::wstring &eventName) = 0;
+    virtual void endEvent() = 0;
+    virtual void setMarker(const std::wstring &markerName) = 0;
+    virtual bool getStatus() = 0;
+};
+
+#if defined(ANGLE_ENABLE_D3D9)
+class D3D9DebugAnnotationWrapper : public DebugAnnotationWrapper
+{
+  public:
+    void beginEvent(const std::wstring &eventName)
+    {
+        D3DPERF_BeginEvent(0, eventName.c_str());
+    }
+
+    void endEvent()
+    {
+        D3DPERF_EndEvent();
+    }
+
+    void setMarker(const std::wstring &markerName)
+    {
+        D3DPERF_SetMarker(0, markerName.c_str());
+    }
+
+    bool getStatus()
+    {
+        return !!D3DPERF_GetStatus();
+    }
+};
+#endif // ANGLE_ENABLE_D3D9
+
+#if defined(ANGLE_ENABLE_D3D11)
+class D3D11DebugAnnotationWrapper : public DebugAnnotationWrapper
+{
+  public:
+
+    D3D11DebugAnnotationWrapper()
+      : mInitialized(false),
+        mD3d11Module(NULL),
+        mUserDefinedAnnotation(NULL)
+    {
+        // D3D11 devices can't be created during DllMain.
+        // We defer device creation until the object is actually used.
+    }
+
+    ~D3D11DebugAnnotationWrapper()
+    {
+        if (mInitialized)
+        {
+            SafeRelease(mUserDefinedAnnotation);
+            FreeLibrary(mD3d11Module);
+        }
+    }
+
+    virtual void beginEvent(const std::wstring &eventName)
+    {
+        initializeDevice();
+
+        mUserDefinedAnnotation->BeginEvent(eventName.c_str());
+    }
+
+    virtual void endEvent()
+    {
+        initializeDevice();
+
+        mUserDefinedAnnotation->EndEvent();
+    }
+
+    virtual void setMarker(const std::wstring &markerName)
+    {
+        initializeDevice();
+
+        mUserDefinedAnnotation->SetMarker(markerName.c_str());
+    }
+
+    virtual bool getStatus()
+    {
+        // ID3DUserDefinedAnnotation::GetStatus doesn't work with the Graphics Diagnostics tools in Visual Studio 2013.
+
+#if defined(_DEBUG) && defined(ANGLE_ENABLE_WINDOWS_STORE)
+        // In the Windows Store, we can use IDXGraphicsAnalysis. The call to GetDebugInterface1 only succeeds if the app is under capture.
+        // This should only be called in DEBUG mode.
+        // If an app links against DXGIGetDebugInterface1 in release mode then it will fail Windows Store ingestion checks.
+        IDXGraphicsAnalysis* graphicsAnalysis;
+        DXGIGetDebugInterface1(0, IID_PPV_ARGS(&graphicsAnalysis));
+        bool underCapture = (graphicsAnalysis != NULL);
+        SafeRelease(graphicsAnalysis);
+        return underCapture;
 #endif
 
-static void output(bool traceFileDebugOnly, PerfOutputFunction perfFunc, const char *format, va_list vararg)
+        // Otherwise, we have to return true here.
+        return true;
+    }
+
+  protected:
+
+    void initializeDevice()
+    {
+        if (!mInitialized)
+        {
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
+            mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
+            ASSERT(mD3d11Module);
+
+            PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
+            ASSERT(D3D11CreateDevice != NULL);
+#endif // !ANGLE_ENABLE_WINDOWS_STORE
+
+            ID3D11Device* device = NULL;
+            ID3D11DeviceContext* context = NULL;
+
+            HRESULT hr = E_FAIL;
+
+            // Create a D3D_DRIVER_TYPE_NULL device, which is much cheaper than other types of device.
+            hr =  D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_NULL, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &device, NULL, &context);
+            ASSERT(SUCCEEDED(hr));
+
+            hr = context->QueryInterface(__uuidof(mUserDefinedAnnotation), reinterpret_cast<void**>(&mUserDefinedAnnotation));
+            ASSERT(SUCCEEDED(hr) && mUserDefinedAnnotation != NULL);
+
+            SafeRelease(device);
+            SafeRelease(context);
+
+            mInitialized = true;
+        }
+    }
+
+    bool mInitialized;
+    HMODULE mD3d11Module;
+    ID3DUserDefinedAnnotation* mUserDefinedAnnotation;
+};
+#endif // ANGLE_ENABLE_D3D11
+
+static DebugAnnotationWrapper* g_DebugAnnotationWrapper = NULL;
+
+void InitializeDebugAnnotations()
 {
-#if defined(ANGLE_ENABLE_PERF) || defined(ANGLE_ENABLE_TRACE)
-    std::string formattedMessage = FormatString(format, vararg);
+#if defined(ANGLE_ENABLE_D3D9)
+    g_DebugAnnotationWrapper = new D3D9DebugAnnotationWrapper();
+#elif defined(ANGLE_ENABLE_D3D11)
+    // If the project uses D3D9 then we can use the D3D9 debug annotations, even with the D3D11 renderer.
+    // However, if D3D9 is unavailable (e.g. in Windows Store), then we use D3D11 debug annotations.
+    // The D3D11 debug annotations are methods on ID3DUserDefinedAnnotation, which is implemented by the DeviceContext.
+    // This doesn't have to be the same DeviceContext that the renderer uses, though.
+    g_DebugAnnotationWrapper = new D3D11DebugAnnotationWrapper();
 #endif
+}
 
-#if defined(ANGLE_ENABLE_PERF)
+void UninitializeDebugAnnotations()
+{
+    if (g_DebugAnnotationWrapper != NULL)
+    {
+        SafeDelete(g_DebugAnnotationWrapper);
+    }
+}
+
+#endif // ANGLE_ENABLE_DEBUG_ANNOTATIONS
+
+enum DebugTraceOutputType
+{
+   DebugTraceOutputTypeNone,
+   DebugTraceOutputTypeSetMarker,
+   DebugTraceOutputTypeBeginEvent
+};
+
+static void output(bool traceInDebugOnly, DebugTraceOutputType outputType, const char *format, va_list vararg)
+{
+#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
+    static std::vector<char> buffer(512);
+
     if (perfActive())
     {
-        // The perf function only accepts wide strings, widen the ascii message
-        static std::wstring wideMessage;
-        if (wideMessage.capacity() < formattedMessage.length())
-        {
-            wideMessage.reserve(formattedMessage.size());
-        }
+        size_t len = FormatStringIntoVector(format, vararg, buffer);
+        std::wstring formattedWideMessage(buffer.begin(), buffer.begin() + len);
 
-        wideMessage.assign(formattedMessage.begin(), formattedMessage.end());
-
-        perfFunc(0, wideMessage.c_str());
+        switch (outputType)
+        {
+            case DebugTraceOutputTypeNone:
+                break;
+            case DebugTraceOutputTypeBeginEvent:
+                g_DebugAnnotationWrapper->beginEvent(formattedWideMessage);
+                break;
+            case DebugTraceOutputTypeSetMarker:
+                g_DebugAnnotationWrapper->setMarker(formattedWideMessage);
+                break;
+        }
     }
-#endif // ANGLE_ENABLE_PERF
+#endif // ANGLE_ENABLE_DEBUG_ANNOTATIONS
 
-#if defined(ANGLE_ENABLE_TRACE)
+#if defined(ANGLE_ENABLE_DEBUG_TRACE)
 #if defined(NDEBUG)
-    if (traceFileDebugOnly)
+    if (traceInDebugOnly)
     {
         return;
     }
 #endif // NDEBUG
+    std::string formattedMessage = FormatString(format, vararg);
 
     static std::ofstream file(TRACE_OUTPUT_FILE, std::ofstream::app);
     if (file)
     {
         file.write(formattedMessage.c_str(), formattedMessage.length());
         file.flush();
     }
 
-#endif // ANGLE_ENABLE_TRACE
+#if defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER)
+    OutputDebugStringA(formattedMessage.c_str());
+#endif // ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER
+
+#endif // ANGLE_ENABLE_DEBUG_TRACE
 }
 
-void trace(bool traceFileDebugOnly, const char *format, ...)
+void trace(bool traceInDebugOnly, const char *format, ...)
 {
     va_list vararg;
     va_start(vararg, format);
-#if defined(ANGLE_ENABLE_PERF)
-    output(traceFileDebugOnly, D3DPERF_SetMarker, format, vararg);
+#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
+    output(traceInDebugOnly, DebugTraceOutputTypeSetMarker, format, vararg);
 #else
-    output(traceFileDebugOnly, NULL, format, vararg);
+    output(traceInDebugOnly, DebugTraceOutputTypeNone, format, vararg);
 #endif
     va_end(vararg);
 }
 
 bool perfActive()
 {
-#if defined(ANGLE_ENABLE_PERF)
-    static bool active = D3DPERF_GetStatus() != 0;
+#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
+    static bool active = g_DebugAnnotationWrapper->getStatus();
     return active;
 #else
     return false;
 #endif
 }
 
 ScopedPerfEventHelper::ScopedPerfEventHelper(const char* format, ...)
 {
-#if !defined(ANGLE_ENABLE_TRACE)
+#if !defined(ANGLE_ENABLE_DEBUG_TRACE)
     if (!perfActive())
     {
         return;
     }
-#endif // !ANGLE_ENABLE_TRACE
+#endif // !ANGLE_ENABLE_DEBUG_TRACE
     va_list vararg;
     va_start(vararg, format);
-#if defined(ANGLE_ENABLE_PERF)
-    output(true, reinterpret_cast<PerfOutputFunction>(D3DPERF_BeginEvent), format, vararg);
+#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
+    output(true, DebugTraceOutputTypeBeginEvent, format, vararg);
 #else
-    output(true, NULL, format, vararg);
-#endif // ANGLE_ENABLE_PERF
+    output(true, DebugTraceOutputTypeNone, format, vararg);
+#endif // ANGLE_ENABLE_DEBUG_ANNOTATIONS
     va_end(vararg);
 }
 
 ScopedPerfEventHelper::~ScopedPerfEventHelper()
 {
-#if defined(ANGLE_ENABLE_PERF)
+#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
     if (perfActive())
     {
-        D3DPERF_EndEvent();
+        g_DebugAnnotationWrapper->endEvent();
     }
 #endif
 }
 }
--- a/gfx/angle/src/common/debug.h
+++ b/gfx/angle/src/common/debug.h
@@ -15,57 +15,60 @@
 #include "common/angleutils.h"
 
 #if !defined(TRACE_OUTPUT_FILE)
 #define TRACE_OUTPUT_FILE "debug.txt"
 #endif
 
 namespace gl
 {
-    // Outputs text to the debugging log
-    void trace(bool traceFileDebugOnly, const char *format, ...);
+    // Outputs text to the debugging log, or the debugging window
+    void trace(bool traceInDebugOnly, const char *format, ...);
 
     // Returns whether D3DPERF is active.
     bool perfActive();
 
     // Pairs a D3D begin event with an end event.
     class ScopedPerfEventHelper
     {
       public:
         ScopedPerfEventHelper(const char* format, ...);
         ~ScopedPerfEventHelper();
 
       private:
         DISALLOW_COPY_AND_ASSIGN(ScopedPerfEventHelper);
     };
+
+    void InitializeDebugAnnotations();
+    void UninitializeDebugAnnotations();
 }
 
 // A macro to output a trace of a function call and its arguments to the debugging log
-#if defined(ANGLE_ENABLE_TRACE) || defined(ANGLE_ENABLE_PERF)
+#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
 #define TRACE(message, ...) gl::trace(true, "trace: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
 #else
 #define TRACE(message, ...) (void(0))
 #endif
 
 // A macro to output a function call and its arguments to the debugging log, to denote an item in need of fixing.
-#if defined(ANGLE_ENABLE_TRACE) || defined(ANGLE_ENABLE_PERF)
+#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
 #define FIXME(message, ...) gl::trace(false, "fixme: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
 #else
 #define FIXME(message, ...) (void(0))
 #endif
 
 // A macro to output a function call and its arguments to the debugging log, in case of error.
-#if defined(ANGLE_ENABLE_TRACE) || defined(ANGLE_ENABLE_PERF)
+#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
 #define ERR(message, ...) gl::trace(false, "err: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
 #else
 #define ERR(message, ...) (void(0))
 #endif
 
 // A macro to log a performance event around a scope.
-#if defined(ANGLE_ENABLE_TRACE) || defined(ANGLE_ENABLE_PERF)
+#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
 #if defined(_MSC_VER)
 #define EVENT(message, ...) gl::ScopedPerfEventHelper scopedPerfEventHelper ## __LINE__("%s" message "\n", __FUNCTION__, __VA_ARGS__);
 #else
 #define EVENT(message, ...) gl::ScopedPerfEventHelper scopedPerfEventHelper(message "\n", ##__VA_ARGS__);
 #endif // _MSC_VER
 #else
 #define EVENT(message, ...) (void(0))
 #endif
@@ -78,17 +81,17 @@ namespace gl
         assert(expression); \
     } while(0)
 #define UNUSED_ASSERTION_VARIABLE(variable)
 #else
 #define ASSERT(expression) (void(0))
 #define UNUSED_ASSERTION_VARIABLE(variable) ((void)variable)
 #endif
 
-#ifndef ANGLE_ENABLE_TRACE
+#ifndef ANGLE_ENABLE_DEBUG_TRACE
 #define UNUSED_TRACE_VARIABLE(variable) ((void)variable)
 #else
 #define UNUSED_TRACE_VARIABLE(variable)
 #endif
 
 // A macro to indicate unimplemented functionality
 
 #if defined (ANGLE_TEST_CONFIG)
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/common/features.h
@@ -0,0 +1,35 @@
+//
+// Copyright (c) 2014 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.
+//
+
+#define ANGLE_DISABLED 0
+#define ANGLE_ENABLED 1
+
+// Feature defaults
+
+// Direct3D9EX
+// The "Debug This Pixel..." feature in PIX often fails when using the
+// D3D9Ex interfaces.  In order to get debug pixel to work on a Vista/Win 7
+// machine, define "ANGLE_D3D9EX=0" in your project file.
+#if !defined(ANGLE_D3D9EX)
+#define ANGLE_D3D9EX ANGLE_ENABLED
+#endif
+
+// Vsync
+// ENABLED allows Vsync to be configured at runtime
+// DISABLED disallows Vsync
+#if !defined(ANGLE_VSYNC)
+#define ANGLE_VSYNC ANGLE_ENABLED
+#endif
+
+// Program binary loading
+#if !defined(ANGLE_PROGRAM_BINARY_LOAD)
+#define ANGLE_PROGRAM_BINARY_LOAD ANGLE_ENABLED
+#endif
+
+// Shader debug info
+#if !defined(ANGLE_SHADER_DEBUG_INFO)
+#define ANGLE_SHADER_DEBUG_INFO ANGLE_DISABLED
+#endif
--- a/gfx/angle/src/common/mathutil.h
+++ b/gfx/angle/src/common/mathutil.h
@@ -104,17 +104,17 @@ inline unsigned int unorm(float x)
     else
     {
         return (unsigned int)(max * x + 0.5f);
     }
 }
 
 inline bool supportsSSE2()
 {
-#ifdef ANGLE_PLATFORM_WINDOWS
+#if ANGLE_PLATFORM_WINDOWS && !defined(_M_ARM)
     static bool checked = false;
     static bool supports = false;
 
     if (checked)
     {
         return supports;
     }
 
--- a/gfx/angle/src/common/platform.h
+++ b/gfx/angle/src/common/platform.h
@@ -29,39 +29,51 @@
       defined(__GNU__) || \
       defined(__QNX__)
 #   define ANGLE_PLATFORM_POSIX 1
 #else
 #   error Unsupported platform.
 #endif
 
 #ifdef ANGLE_PLATFORM_WINDOWS
+#   if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP
+#       define ANGLE_ENABLE_WINDOWS_STORE 1
+#   endif
 #   ifndef STRICT
 #       define STRICT 1
 #   endif
 #   ifndef WIN32_LEAN_AND_MEAN
 #       define WIN32_LEAN_AND_MEAN 1
 #   endif
 #   ifndef NOMINMAX
 #       define NOMINMAX 1
 #   endif
 
 #   include <windows.h>
 #   include <intrin.h>
 
-#   if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_PERF)
+#   if defined(ANGLE_ENABLE_D3D9)
 #       include <d3d9.h>
 #       include <d3dcompiler.h>
 #   endif
 
 #   if defined(ANGLE_ENABLE_D3D11)
 #       include <d3d10_1.h>
 #       include <d3d11.h>
+#       include <d3d11_1.h>
 #       include <dxgi.h>
 #       include <dxgi1_2.h>
 #       include <d3dcompiler.h>
 #   endif
 
+#   if defined(ANGLE_ENABLE_WINDOWS_STORE)
+#       include <dxgi1_3.h>
+#       if defined(_DEBUG)
+#           include <DXProgrammableCapture.h>
+#           include <dxgidebug.h>
+#       endif
+#   endif
+
 #   undef near
 #   undef far
 #endif
 
 #endif // COMMON_PLATFORM_H_
--- a/gfx/angle/src/common/tls.cpp
+++ b/gfx/angle/src/common/tls.cpp
@@ -5,22 +5,60 @@
 //
 
 // tls.cpp: Simple cross-platform interface for thread local storage.
 
 #include "common/tls.h"
 
 #include <assert.h>
 
+#ifdef ANGLE_ENABLE_WINDOWS_STORE
+#include <vector>
+#include <set>
+#include <map>
+#include <mutex>
+
+#include <wrl/client.h>
+#include <wrl/async.h>
+#include <Windows.System.Threading.h>
+
+using namespace std;
+using namespace Windows::Foundation;
+using namespace ABI::Windows::System::Threading;
+
+// Thread local storage for Windows Store support
+typedef vector<void*> ThreadLocalData;
+
+static __declspec(thread) ThreadLocalData* currentThreadData = nullptr;
+static set<ThreadLocalData*> allThreadData;
+static DWORD nextTlsIndex = 0;
+static vector<DWORD> freeTlsIndices;
+
+#endif
+
 TLSIndex CreateTLSIndex()
 {
     TLSIndex index;
 
 #ifdef ANGLE_PLATFORM_WINDOWS
+#ifdef ANGLE_ENABLE_WINDOWS_STORE
+    if (!freeTlsIndices.empty())
+    {
+        DWORD result = freeTlsIndices.back();
+        freeTlsIndices.pop_back();
+        index = result;
+    }
+    else
+    {
+        index = nextTlsIndex++;
+    }
+#else
     index = TlsAlloc();
+#endif
+
 #elif defined(ANGLE_PLATFORM_POSIX)
     // Create global pool key
     if ((pthread_key_create(&index, NULL)) != 0)
     {
         index = TLS_INVALID_INDEX;
     }
 #endif
 
@@ -32,43 +70,87 @@ bool DestroyTLSIndex(TLSIndex index)
 {
     assert(index != TLS_INVALID_INDEX && "DestroyTLSIndex(): Invalid TLS Index");
     if (index == TLS_INVALID_INDEX)
     {
         return false;
     }
 
 #ifdef ANGLE_PLATFORM_WINDOWS
+#ifdef ANGLE_ENABLE_WINDOWS_STORE
+    assert(index < nextTlsIndex);
+    assert(find(freeTlsIndices.begin(), freeTlsIndices.end(), index) == freeTlsIndices.end());
+
+    freeTlsIndices.push_back(index);
+    for (auto threadData : allThreadData)
+    {
+        if (threadData->size() > index)
+        {
+            threadData->at(index) = nullptr;
+        }
+    }
+    return true;
+#else
     return (TlsFree(index) == TRUE);
+#endif
 #elif defined(ANGLE_PLATFORM_POSIX)
     return (pthread_key_delete(index) == 0);
 #endif
 }
 
 bool SetTLSValue(TLSIndex index, void *value)
 {
     assert(index != TLS_INVALID_INDEX && "SetTLSValue(): Invalid TLS Index");
     if (index == TLS_INVALID_INDEX)
     {
         return false;
     }
 
 #ifdef ANGLE_PLATFORM_WINDOWS
+#ifdef ANGLE_ENABLE_WINDOWS_STORE
+    ThreadLocalData* threadData = currentThreadData;
+    if (!threadData)
+    {
+        threadData = new ThreadLocalData(index + 1, nullptr);
+        allThreadData.insert(threadData);
+        currentThreadData = threadData;
+    }
+    else if (threadData->size() <= index)
+    {
+        threadData->resize(index + 1, nullptr);
+    }
+
+    threadData->at(index) = value;
+    return true;
+#else
     return (TlsSetValue(index, value) == TRUE);
+#endif
 #elif defined(ANGLE_PLATFORM_POSIX)
     return (pthread_setspecific(index, value) == 0);
 #endif
 }
 
 void *GetTLSValue(TLSIndex index)
 {
     assert(index != TLS_INVALID_INDEX && "GetTLSValue(): Invalid TLS Index");
     if (index == TLS_INVALID_INDEX)
     {
         return NULL;
     }
 
 #ifdef ANGLE_PLATFORM_WINDOWS
+#ifdef ANGLE_ENABLE_WINDOWS_STORE
+    ThreadLocalData* threadData = currentThreadData;
+    if (threadData && threadData->size() > index)
+    {
+        return threadData->at(index);
+    }
+    else
+    {
+        return nullptr;
+    }
+#else
     return TlsGetValue(index);
+#endif
 #elif defined(ANGLE_PLATFORM_POSIX)
     return pthread_getspecific(index);
 #endif
 }
--- a/gfx/angle/src/common/tls.h
+++ b/gfx/angle/src/common/tls.h
@@ -7,27 +7,38 @@
 // tls.h: Simple cross-platform interface for thread local storage.
 
 #ifndef COMMON_TLS_H_
 #define COMMON_TLS_H_
 
 #include "common/platform.h"
 
 #ifdef ANGLE_PLATFORM_WINDOWS
+
+// TLS does not exist for Windows Store and needs to be emulated
+#   ifdef ANGLE_ENABLE_WINDOWS_STORE
+#       define TLS_OUT_OF_INDEXES -1
+#       ifndef CREATE_SUSPENDED
+#           define CREATE_SUSPENDED 0x00000004
+#       endif
+#   endif
     typedef DWORD TLSIndex;
 #   define TLS_INVALID_INDEX (TLS_OUT_OF_INDEXES)
 #elif defined(ANGLE_PLATFORM_POSIX)
 #   include <pthread.h>
 #   include <semaphore.h>
 #   include <errno.h>
     typedef pthread_key_t TLSIndex;
 #   define TLS_INVALID_INDEX (static_cast<TLSIndex>(-1))
 #else
 #   error Unsupported platform.
 #endif
 
+// TODO(kbr): for POSIX platforms this will have to be changed to take
+// in a destructor function pointer, to allow the thread-local storage
+// to be properly deallocated upon thread exit.
 TLSIndex CreateTLSIndex();
 bool DestroyTLSIndex(TLSIndex index);
 
 bool SetTLSValue(TLSIndex index, void *value);
 void *GetTLSValue(TLSIndex index);
 
 #endif // COMMON_TLS_H_
--- a/gfx/angle/src/common/utilities.cpp
+++ b/gfx/angle/src/common/utilities.cpp
@@ -7,16 +7,23 @@
 // utilities.cpp: Conversion functions and other utility routines.
 
 #include "common/utilities.h"
 #include "common/mathutil.h"
 #include "common/platform.h"
 
 #include <set>
 
+#if defined(ANGLE_ENABLE_WINDOWS_STORE)
+#  include <wrl.h>
+#  include <wrl/wrappers/corewrappers.h>
+#  include <windows.applicationmodel.core.h>
+#  include <windows.graphics.display.h>
+#endif
+
 namespace gl
 {
 
 int VariableComponentCount(GLenum type)
 {
     return VariableRowCount(type) * VariableColumnCount(type);
 }
 
@@ -434,16 +441,17 @@ int VariableSortOrder(GLenum type)
       default:
         UNREACHABLE();
         return 0;
     }
 }
 
 }
 
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
 std::string getTempPath()
 {
 #ifdef ANGLE_PLATFORM_WINDOWS
     char path[MAX_PATH];
     DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
     if (pathLen == 0)
     {
         UNREACHABLE();
@@ -471,8 +479,38 @@ void writeFile(const char* path, const v
     {
         UNREACHABLE();
         return;
     }
 
     fwrite(content, sizeof(char), size, file);
     fclose(file);
 }
+#endif // !ANGLE_ENABLE_WINDOWS_STORE
+
+#if defined(ANGLE_ENABLE_WINDOWS_STORE)
+
+void Sleep(unsigned long dwMilliseconds)
+{
+    static HANDLE singletonEvent = nullptr;
+    HANDLE sleepEvent = singletonEvent;
+    if (!sleepEvent)
+    {
+        sleepEvent = CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
+
+        if (!sleepEvent)
+            return;
+
+        HANDLE previousEvent = InterlockedCompareExchangePointerRelease(&singletonEvent, sleepEvent, nullptr);
+
+        if (previousEvent)
+        {
+            // Back out if multiple threads try to demand create at the same time.
+            CloseHandle(sleepEvent);
+            sleepEvent = previousEvent;
+        }
+    }
+
+    // Emulate sleep by waiting with timeout on an event that is never signalled.
+    WaitForSingleObjectEx(sleepEvent, dwMilliseconds, false);
+}
+
+#endif // ANGLE_ENABLE_WINDOWS_STORE
--- a/gfx/angle/src/common/utilities.h
+++ b/gfx/angle/src/common/utilities.h
@@ -41,12 +41,18 @@ bool IsTriangleMode(GLenum drawMode);
 // [OpenGL ES 3.0.2] Section 2.3.1 page 14
 // Data Conversion For State-Setting Commands
 // Floating-point values are rounded to the nearest integer, instead of truncated, as done by static_cast.
 template <typename outT> outT iround(GLfloat value) { return static_cast<outT>(value > 0.0f ? floor(value + 0.5f) : ceil(value - 0.5f)); }
 template <typename outT> outT uiround(GLfloat value) { return static_cast<outT>(value + 0.5f); }
 
 }
 
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
 std::string getTempPath();
 void writeFile(const char* path, const void* data, size_t size);
+#endif
+
+#if defined(ANGLE_ENABLE_WINDOWS_STORE)
+void Sleep(_In_ unsigned long dwMilliseconds);
+#endif
 
 #endif  // LIBGLESV2_UTILITIES_H
--- a/gfx/angle/src/common/win32/NativeWindow.cpp
+++ b/gfx/angle/src/common/win32/NativeWindow.cpp
@@ -15,16 +15,31 @@ bool isValidEGLNativeWindowType(EGLNativ
 }
 
 namespace rx
 {
 NativeWindow::NativeWindow(EGLNativeWindowType window) : mWindow(window)
 {
 }
 
+bool NativeWindow::initialize()
+{ 
+    return true; 
+}
+
+bool NativeWindow::getClientRect(LPRECT rect)
+{
+    return GetClientRect(mWindow, rect) == TRUE;
+}
+
+bool NativeWindow::isIconic()
+{
+    return IsIconic(mWindow) == TRUE;
+}
+
 #ifdef ANGLE_ENABLE_D3D11
 HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory,
                                       DXGI_FORMAT format, unsigned int width, unsigned int height,
                                       DXGISwapChain** swapChain)
 {
     if (device == NULL || factory == NULL || swapChain == NULL || width == 0 || height == 0)
     {
         return E_INVALIDARG;
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/common/winrt/CoreWindowNativeWindow.cpp
@@ -0,0 +1,184 @@
+//
+// Copyright (c) 2002-2014 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.
+//
+
+// CoreWindowNativeWindow.cpp: NativeWindow for managing ICoreWindow native window types.
+
+#include <windows.graphics.display.h>
+#include "common/winrt/CoreWindowNativeWindow.h"
+using namespace ABI::Windows::Foundation::Collections;
+
+CoreWindowNativeWindow::~CoreWindowNativeWindow()
+{
+    unregisterForSizeChangeEvents();
+}
+
+bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet *propertySet)
+{
+    ComPtr<IPropertySet> props = propertySet;
+    ComPtr<IInspectable> win = window;
+    SIZE swapChainSize = {};
+    bool swapChainSizeSpecified = false;
+    HRESULT result = S_OK;
+
+    // IPropertySet is an optional parameter and can null.
+    // If one is specified, cache as an IMap and read the properties
+    // used for initial host initialization.
+    if (propertySet)
+    {
+        result = props.As(&mPropertyMap);
+        if (SUCCEEDED(result))
+        {
+            // The EGLRenderSurfaceSizeProperty is optional and may be missing.  The IPropertySet
+            // was prevalidated to contain the EGLNativeWindowType before being passed to
+            // this host.
+            result = getOptionalSizePropertyValue(mPropertyMap, EGLRenderSurfaceSizeProperty, &swapChainSize, &swapChainSizeSpecified);
+        }
+    }
+
+    if (SUCCEEDED(result))
+    {
+        result = win.As(&mCoreWindow);
+    }
+
+    if (SUCCEEDED(result))
+    {
+        // If a swapchain size is specfied, then the automatic resize
+        // behaviors implemented by the host should be disabled.  The swapchain
+        // will be still be scaled when being rendered to fit the bounds
+        // of the host.
+        // Scaling of the swapchain output occurs automatically because if
+        // the scaling mode setting DXGI_SCALING_STRETCH on the swapchain.
+        if (swapChainSizeSpecified)
+        {
+            mClientRect = { 0, 0, swapChainSize.cx, swapChainSize.cy };
+            mSupportsSwapChainResize = false;
+        }
+        else
+        {
+            result = getCoreWindowSizeInPixels(mCoreWindow, &mClientRect);
+        }
+    }
+
+    if (SUCCEEDED(result))
+    {
+        mNewClientRect = mClientRect;
+        mClientRectChanged = false;
+        return registerForSizeChangeEvents();
+    }
+
+    return false;
+}
+
+bool CoreWindowNativeWindow::registerForSizeChangeEvents()
+{
+    ComPtr<IWindowSizeChangedEventHandler> sizeChangedHandler;
+    HRESULT result = Microsoft::WRL::MakeAndInitialize<CoreWindowSizeChangedHandler>(sizeChangedHandler.ReleaseAndGetAddressOf(), this->shared_from_this());
+    if (SUCCEEDED(result))
+    {
+        result = mCoreWindow->add_SizeChanged(sizeChangedHandler.Get(), &mSizeChangedEventToken);
+    }
+
+    if (SUCCEEDED(result))
+    {
+        return true;
+    }
+
+    return false;
+}
+
+void CoreWindowNativeWindow::unregisterForSizeChangeEvents()
+{
+    if (mCoreWindow)
+    {
+        (void)mCoreWindow->remove_SizeChanged(mSizeChangedEventToken);
+    }
+    mSizeChangedEventToken.value = 0;
+}
+
+HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain)
+{
+    if (device == NULL || factory == NULL || swapChain == NULL || width == 0 || height == 0)
+    {
+        return E_INVALIDARG;
+    }
+
+    DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 };
+    swapChainDesc.Width = width;
+    swapChainDesc.Height = height;
+    swapChainDesc.Format = format;
+    swapChainDesc.Stereo = FALSE;
+    swapChainDesc.SampleDesc.Count = 1;
+    swapChainDesc.SampleDesc.Quality = 0;
+    swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
+    swapChainDesc.BufferCount = 2;
+    swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
+    swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
+
+    *swapChain = nullptr;
+
+    ComPtr<IDXGISwapChain1> newSwapChain;
+    HRESULT result = factory->CreateSwapChainForCoreWindow(device, mCoreWindow.Get(), &swapChainDesc, nullptr, newSwapChain.ReleaseAndGetAddressOf());
+    if (SUCCEEDED(result))
+    {
+
+#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+        // Test if swapchain supports resize.  On Windows Phone devices, this will return DXGI_ERROR_UNSUPPORTED.  On
+        // other devices DXGI_ERROR_INVALID_CALL should be returned because the combination of flags passed
+        // (DXGI_SWAP_CHAIN_FLAG_NONPREROTATED | DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE) are invalid flag combinations.
+        if (newSwapChain->ResizeBuffers(swapChainDesc.BufferCount, swapChainDesc.Width, swapChainDesc.Height, swapChainDesc.Format, DXGI_SWAP_CHAIN_FLAG_NONPREROTATED | DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE) == DXGI_ERROR_UNSUPPORTED)
+        {
+            mSupportsSwapChainResize = false;
+        }
+#endif // (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+
+        result = newSwapChain.CopyTo(swapChain);
+    }
+
+    if (SUCCEEDED(result))
+    {
+        // If automatic swapchain resize behaviors have been disabled, then
+        // unregister for the resize change events.
+        if (mSupportsSwapChainResize == false)
+        {
+            unregisterForSizeChangeEvents();
+        }
+    }
+
+    return result;
+}
+
+HRESULT getCoreWindowSizeInPixels(const ComPtr<ABI::Windows::UI::Core::ICoreWindow>& coreWindow, RECT *windowSize)
+{
+    ABI::Windows::Foundation::Rect bounds;
+    HRESULT result = coreWindow->get_Bounds(&bounds);
+    if (SUCCEEDED(result))
+    {
+        *windowSize = { 0, 0, ConvertDipsToPixels(bounds.Width), ConvertDipsToPixels(bounds.Height) };
+    }
+
+    return result;
+}
+
+static float GetLogicalDpi()
+{
+    ComPtr<ABI::Windows::Graphics::Display::IDisplayPropertiesStatics> displayProperties;
+    float dpi = 96.0f;
+
+    if (SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), displayProperties.GetAddressOf())))
+    {
+        if (SUCCEEDED(displayProperties->get_LogicalDpi(&dpi)))
+        {
+            return dpi;
+        }
+    }
+    return dpi;
+}
+
+long ConvertDipsToPixels(float dips)
+{
+    static const float dipsPerInch = 96.0f;
+    return lround((dips * GetLogicalDpi() / dipsPerInch));
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/common/winrt/CoreWindowNativeWindow.h
@@ -0,0 +1,71 @@
+//
+// Copyright (c) 2002-2014 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.
+//
+
+// CoreWindowNativeWindow.h: NativeWindow for managing ICoreWindow native window types.
+
+#ifndef COMMON_COREWINDOWNATIVEWINDOW_H_
+#define COMMON_COREWINDOWNATIVEWINDOW_H_
+
+#include "common/winrt/IInspectableNativeWindow.h"
+#include <memory>
+
+typedef ABI::Windows::Foundation::__FITypedEventHandler_2_Windows__CUI__CCore__CCoreWindow_Windows__CUI__CCore__CWindowSizeChangedEventArgs_t IWindowSizeChangedEventHandler;
+long ConvertDipsToPixels(float dips);
+
+class CoreWindowNativeWindow : public IInspectableNativeWindow, public std::enable_shared_from_this<CoreWindowNativeWindow>
+{
+  public:
+    ~CoreWindowNativeWindow();
+    bool initialize(EGLNativeWindowType window, IPropertySet *propertySet);
+    bool registerForSizeChangeEvents();
+    void unregisterForSizeChangeEvents();
+    HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain);
+  private:
+    ComPtr<ABI::Windows::UI::Core::ICoreWindow> mCoreWindow;
+    ComPtr<IMap<HSTRING, IInspectable*>> mPropertyMap;
+};
+
+[uuid(7F924F66-EBAE-40E5-A10B-B8F35E245190)]
+class CoreWindowSizeChangedHandler :
+    public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, IWindowSizeChangedEventHandler>
+{
+  public:
+    CoreWindowSizeChangedHandler() { }
+    HRESULT RuntimeClassInitialize(std::shared_ptr<IInspectableNativeWindow> host)
+    {
+        if (!host)
+        {
+            return E_INVALIDARG;
+        }
+
+        mHost = host;
+        return S_OK;
+    }
+
+    // IWindowSizeChangedEventHandler
+    IFACEMETHOD(Invoke)(ABI::Windows::UI::Core::ICoreWindow *sender, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *e)
+    {
+        std::shared_ptr<IInspectableNativeWindow> host = mHost.lock();
+        if (host)
+        {
+            ABI::Windows::Foundation::Size windowSize;
+            if (SUCCEEDED(e->get_Size(&windowSize)))
+            {
+                SIZE windowSizeInPixels = { ConvertDipsToPixels(windowSize.Width), ConvertDipsToPixels(windowSize.Height) };
+                host->setNewClientSize(windowSizeInPixels);
+            }
+        }
+
+        return S_OK;
+    }
+
+  private:
+    std::weak_ptr<IInspectableNativeWindow> mHost;
+};
+
+HRESULT getCoreWindowSizeInPixels(const ComPtr<ABI::Windows::UI::Core::ICoreWindow>& coreWindow, RECT *windowSize);
+
+#endif // COMMON_COREWINDOWNATIVEWINDOW_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/common/winrt/IInspectableNativeWindow.cpp
@@ -0,0 +1,245 @@
+//
+// Copyright (c) 2002-2014 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.
+//
+
+// iinspectablehost.cpp: NativeWindow base class for managing IInspectable native window types.
+
+#include "common/winrt/CoreWindowNativeWindow.h"
+
+namespace rx
+{
+NativeWindow::NativeWindow(EGLNativeWindowType window)
+{
+    mWindow = window;
+}
+
+bool NativeWindow::initialize()
+{
+    // If the native window type is a IPropertySet, extract the
+    // EGLNativeWindowType (IInspectable) and initialize the
+    // proper host with this IPropertySet.
+    ComPtr<ABI::Windows::Foundation::Collections::IPropertySet> propertySet;
+    ComPtr<IInspectable> eglNativeWindow;
+    if (isEGLConfiguredPropertySet(mWindow, &propertySet, &eglNativeWindow))
+    {
+        // A property set was found and the EGLNativeWindowType was
+        // retrieved. The mWindow member of the host to must be updated
+        // to use the EGLNativeWindowType specified in the property set.
+        // mWindow is treated as a raw pointer not an AddRef'd interface, so
+        // the old mWindow does not need a Release() before this assignment.
+        mWindow = eglNativeWindow.Get();
+    }
+
+    // If the native window is a ICoreWindow, initialize a CoreWindowNativeWindow
+    ComPtr<ABI::Windows::UI::Core::ICoreWindow> coreWindow;
+    if (isCoreWindow(mWindow, &coreWindow))
+    {
+        mImpl = std::make_shared<CoreWindowNativeWindow>();
+        if (mImpl)
+        {
+            return mImpl->initialize(mWindow, propertySet.Get());
+        }
+    }
+    else
+    {
+        ERR("Invalid IInspectable EGLNativeWindowType detected. Valid IInspectables include ICoreWindow and IPropertySet");
+    }
+
+    return false;
+}
+
+bool NativeWindow::getClientRect(RECT *rect)
+{
+    if (mImpl)
+    {
+        return mImpl->getClientRect(rect);
+    }
+
+    return false;
+}
+
+bool NativeWindow::isIconic()
+{
+    return false;
+}
+
+HRESULT NativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain)
+{
+    if (mImpl)
+    {
+        return mImpl->createSwapChain(device, factory, format, width, height, swapChain);
+    }
+
+    return E_UNEXPECTED;
+}
+
+}
+
+bool isCoreWindow(EGLNativeWindowType window, ComPtr<ABI::Windows::UI::Core::ICoreWindow> *coreWindow)
+{
+    if (!window)
+    {
+        return false;
+    }
+
+    ComPtr<IInspectable> win = window;
+    ComPtr<ABI::Windows::UI::Core::ICoreWindow> coreWin;
+    if (SUCCEEDED(win.As(&coreWin)))
+    {
+        if (coreWindow != nullptr)
+        {
+            *coreWindow = coreWin.Detach();
+        }
+        return true;
+    }
+
+    return false;
+}
+
+bool isEGLConfiguredPropertySet(EGLNativeWindowType window, ABI::Windows::Foundation::Collections::IPropertySet **propertySet, IInspectable **eglNativeWindow)
+{
+    if (!window)
+    {
+        return false;
+    }
+
+    ComPtr<IInspectable> props = window;
+    ComPtr<IPropertySet> propSet;
+    ComPtr<IInspectable> nativeWindow;
+    ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>> propMap;
+    boolean hasEglNativeWindowPropertyKey = false;
+
+    HRESULT result = props.As(&propSet);
+    if (SUCCEEDED(result))
+    {
+        result = propSet.As(&propMap);
+    }
+
+    // Look for the presence of the EGLNativeWindowType in the property set
+    if (SUCCEEDED(result))
+    {
+        result = propMap->HasKey(HStringReference(EGLNativeWindowTypeProperty).Get(), &hasEglNativeWindowPropertyKey);
+    }
+
+    // If the IPropertySet does not contain the required EglNativeWindowType key, the property set is
+    // considered invalid.
+    if (SUCCEEDED(result) && !hasEglNativeWindowPropertyKey)
+    {
+        ERR("Could not find EGLNativeWindowTypeProperty in IPropertySet. Valid EGLNativeWindowTypeProperty values include ICoreWindow");
+        return false;
+    }
+
+    // The EglNativeWindowType property exists, so retreive the IInspectable that represents the EGLNativeWindowType
+    if (SUCCEEDED(result) && hasEglNativeWindowPropertyKey)
+    {
+        result = propMap->Lookup(HStringReference(EGLNativeWindowTypeProperty).Get(), &nativeWindow);
+    }
+
+    if (SUCCEEDED(result))
+    {
+        if (propertySet != nullptr)
+        {
+            result = propSet.CopyTo(propertySet);
+        }
+    }
+
+    if (SUCCEEDED(result))
+    {
+        if (eglNativeWindow != nullptr)
+        {
+            result = nativeWindow.CopyTo(eglNativeWindow);
+        }
+    }
+
+    if (SUCCEEDED(result))
+    {
+        return true;
+    }
+
+    return false;
+}
+
+// A Valid EGLNativeWindowType IInspectable can only be:
+//
+// ICoreWindow
+// IPropertySet
+// 
+// Anything else will be rejected as an invalid IInspectable.
+bool isValidEGLNativeWindowType(EGLNativeWindowType window)
+{
+    return isCoreWindow(window) || isEGLConfiguredPropertySet(window);
+}
+
+// Attempts to read an optional SIZE property value that is assumed to be in the form of
+// an ABI::Windows::Foundation::Size.  This function validates the Size value before returning 
+// it to the caller.
+//
+// Possible return values are:
+// S_OK, valueExists == true - optional SIZE value was successfully retrieved and validated
+// S_OK, valueExists == false - optional SIZE value was not found
+// E_INVALIDARG, valueExists = false - optional SIZE value was malformed in the property set.
+//    * Incorrect property type ( must be PropertyType_Size)
+//    * Invalid property value (width/height must be > 0)
+// Additional errors may be returned from IMap or IPropertyValue
+//
+HRESULT getOptionalSizePropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>>& propertyMap, const wchar_t *propertyName, SIZE *value, bool *valueExists)
+{
+    if (!propertyMap || !propertyName || !value || !valueExists)
+    {
+        return false;
+    }
+
+    // Assume that the value does not exist
+    *valueExists = false;
+    *value = { 0, 0 };
+
+    ComPtr<ABI::Windows::Foundation::IPropertyValue> propertyValue;
+    ABI::Windows::Foundation::PropertyType propertyType = ABI::Windows::Foundation::PropertyType::PropertyType_Empty;
+    Size sizeValue = { 0, 0 };
+    boolean hasKey = false;
+
+    HRESULT result = propertyMap->HasKey(HStringReference(propertyName).Get(), &hasKey);
+    if (SUCCEEDED(result) && !hasKey)
+    {
+        // Value does not exist, so return S_OK and set the exists parameter to false to indicate
+        // that a the optional property does not exist.
+        *valueExists = false;
+        return S_OK;
+    }
+
+    if (SUCCEEDED(result))
+    {
+        result = propertyMap->Lookup(HStringReference(propertyName).Get(), &propertyValue);
+    }
+
+    if (SUCCEEDED(result))
+    {
+        result = propertyValue->get_Type(&propertyType);
+    }
+
+    // Check if the expected Size property is of PropertyType_Size type.
+    if (SUCCEEDED(result) && propertyType == ABI::Windows::Foundation::PropertyType::PropertyType_Size)
+    {
+        if (SUCCEEDED(propertyValue->GetSize(&sizeValue)) && (sizeValue.Width > 0 && sizeValue.Height > 0))
+        {
+            // A valid property value exists
+            *value = { static_cast<long>(sizeValue.Width), static_cast<long>(sizeValue.Height) };
+            *valueExists = true;
+            result = S_OK;
+        }
+        else
+        {
+            // An invalid Size property was detected. Width/Height values must > 0
+            result = E_INVALIDARG;
+        }
+    }
+    else
+    {
+        // An invalid property type was detected. Size property must be of PropertyType_Size
+        result = E_INVALIDARG;
+    }
+
+    return result;
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/common/winrt/IInspectableNativeWindow.h
@@ -0,0 +1,86 @@
+//
+// Copyright (c) 2002-2014 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.
+//
+
+// IInspectableNativeWindow.h: Host specific implementation interface for
+// managing IInspectable native window types.
+
+#ifndef COMMON_IINSPECTABLENATIVEWINDOW_H_
+#define COMMON_IINSPECTABLENATIVEWINDOW_H_
+
+#include "common/platform.h"
+#include "common/NativeWindow.h"
+#include "angle_windowsstore.h"
+
+#include <windows.ui.xaml.h>
+#include <windows.ui.xaml.media.dxinterop.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
+
+class IInspectableNativeWindow
+{
+  public:
+    virtual bool initialize(EGLNativeWindowType window, IPropertySet *propertySet) = 0;
+    virtual HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain) = 0;
+    virtual bool registerForSizeChangeEvents() = 0;
+    virtual void unregisterForSizeChangeEvents() = 0;
+    virtual HRESULT scaleSwapChain(const SIZE& newSize) { return S_OK; }
+
+    IInspectableNativeWindow() :
+        mSupportsSwapChainResize(true),
+        mRequiresSwapChainScaling(false),
+        mClientRectChanged(false),
+        mClientRect({0,0,0,0}),
+        mNewClientRect({0,0,0,0})
+    {
+        mSizeChangedEventToken.value = 0;
+    }
+
+    virtual ~IInspectableNativeWindow(){}
+
+    bool getClientRect(RECT *rect)
+    {
+        if (mClientRectChanged && mSupportsSwapChainResize)
+        {
+            mClientRect = mNewClientRect;
+        }
+
+        *rect = mClientRect;
+
+        return true;
+    }
+
+    void setNewClientSize(const SIZE &newSize)
+    {
+        if (mSupportsSwapChainResize && !mRequiresSwapChainScaling)
+        {
+            mNewClientRect = { 0, 0, newSize.cx, newSize.cy };
+            mClientRectChanged = true;
+        }
+
+        if (mRequiresSwapChainScaling)
+        {
+            scaleSwapChain(newSize);
+        }
+    }
+
+protected:
+    bool mSupportsSwapChainResize;
+    bool mRequiresSwapChainScaling;
+    RECT mClientRect;
+    RECT mNewClientRect;
+    bool mClientRectChanged;
+
+    EventRegistrationToken mSizeChangedEventToken;
+};
+
+bool isCoreWindow(EGLNativeWindowType window, ComPtr<ABI::Windows::UI::Core::ICoreWindow> *coreWindow = nullptr);
+bool isEGLConfiguredPropertySet(EGLNativeWindowType window, ABI::Windows::Foundation::Collections::IPropertySet **propertySet = nullptr, IInspectable **inspectable = nullptr);
+HRESULT getOptionalSizePropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>>& propertyMap, const wchar_t *propertyName, SIZE *value, bool *valueExists);
+
+#endif // COMMON_IINSPECTABLENATIVEWINDOW_H_
--- a/gfx/angle/src/compiler.gypi
+++ b/gfx/angle/src/compiler.gypi
@@ -200,16 +200,27 @@
     # anything also change angle/BUILD.gn
     'targets':
     [
         {
             'target_name': 'preprocessor',
             'type': 'static_library',
             'includes': [ '../build/common_defines.gypi', ],
             'sources': [ '<@(angle_preprocessor_sources)', ],
+            'conditions':
+            [
+                ['angle_build_winrt==1',
+                {
+                    'msvs_enable_winrt' : '1',
+                }],
+                ['angle_build_winphone==1',
+                {
+                    'msvs_enable_winphone' : '1',
+                }],
+            ],
         },
         {
             'target_name': 'translator_lib',
             'type': 'static_library',
             'dependencies': [ 'preprocessor' ],
             'includes': [ '../build/common_defines.gypi', ],
             'include_dirs':
             [
@@ -228,16 +239,27 @@
             ],
             'msvs_settings':
             {
               'VCLibrarianTool':
               {
                 'AdditionalOptions': ['/ignore:4221']
               },
             },
+            'conditions':
+            [
+                ['angle_build_winrt==1',
+                {
+                    'msvs_enable_winrt' : '1',
+                }],
+                ['angle_build_winphone==1',
+                {
+                    'msvs_enable_winphone' : '1',
+                }],
+            ],
         },
 
         {
             'target_name': 'translator',
             'type': '<(component)',
             'dependencies': [ 'translator_lib' ],
             'includes': [ '../build/common_defines.gypi', ],
             'include_dirs':
@@ -249,16 +271,27 @@
             [
                 'ANGLE_TRANSLATOR_IMPLEMENTATION',
             ],
             'sources':
             [
                 'compiler/translator/ShaderLang.cpp',
                 'compiler/translator/ShaderVars.cpp'
             ],
+            'conditions':
+            [
+                ['angle_build_winrt==1',
+                {
+                    'msvs_enable_winrt' : '1',
+                }],
+                ['angle_build_winphone==1',
+                {
+                    'msvs_enable_winphone' : '1',
+                }],
+            ],
         },
 
         {
             'target_name': 'translator_static',
             'type': 'static_library',
             'dependencies': [ 'translator_lib' ],
             'includes': [ '../build/common_defines.gypi', ],
             'include_dirs':
@@ -277,11 +310,22 @@
                     'ANGLE_TRANSLATOR_STATIC',
                 ],
             },
             'sources':
             [
                 'compiler/translator/ShaderLang.cpp',
                 'compiler/translator/ShaderVars.cpp'
             ],
+            'conditions':
+            [
+                ['angle_build_winrt==1',
+                {
+                    'msvs_enable_winrt' : '1',
+                }],
+                ['angle_build_winphone==1',
+                {
+                    'msvs_enable_winphone' : '1',
+                }],
+            ],
         },
     ],
 }
--- a/gfx/angle/src/compiler/preprocessor/DirectiveHandlerBase.h
+++ b/gfx/angle/src/compiler/preprocessor/DirectiveHandlerBase.h
@@ -24,17 +24,18 @@ class DirectiveHandler
     virtual ~DirectiveHandler();
 
     virtual void handleError(const SourceLocation &loc,
                              const std::string &msg) = 0;
 
     // Handle pragma of form: #pragma name[(value)]
     virtual void handlePragma(const SourceLocation &loc,
                               const std::string &name,
-                              const std::string &value) = 0;
+                              const std::string &value,
+                              bool stdgl) = 0;
 
     virtual void handleExtension(const SourceLocation &loc,
                                  const std::string &name,
                                  const std::string &behavior) = 0;
 
     virtual void handleVersion(const SourceLocation &loc,
                                int version) = 0;
 };
--- a/gfx/angle/src/compiler/preprocessor/DirectiveParser.cpp
+++ b/gfx/angle/src/compiler/preprocessor/DirectiveParser.cpp
@@ -33,29 +33,29 @@ enum DirectiveType
     DIRECTIVE_PRAGMA,
     DIRECTIVE_EXTENSION,
     DIRECTIVE_VERSION,
     DIRECTIVE_LINE
 };
 
 DirectiveType getDirective(const pp::Token *token)
 {
-    static const std::string kDirectiveDefine("define");
-    static const std::string kDirectiveUndef("undef");
-    static const std::string kDirectiveIf("if");
-    static const std::string kDirectiveIfdef("ifdef");
-    static const std::string kDirectiveIfndef("ifndef");
-    static const std::string kDirectiveElse("else");
-    static const std::string kDirectiveElif("elif");
-    static const std::string kDirectiveEndif("endif");
-    static const std::string kDirectiveError("error");
-    static const std::string kDirectivePragma("pragma");
-    static const std::string kDirectiveExtension("extension");
-    static const std::string kDirectiveVersion("version");
-    static const std::string kDirectiveLine("line");
+    const char kDirectiveDefine[] = "define";
+    const char kDirectiveUndef[] = "undef";
+    const char kDirectiveIf[] = "if";
+    const char kDirectiveIfdef[] = "ifdef";
+    const char kDirectiveIfndef[] = "ifndef";
+    const char kDirectiveElse[] = "else";
+    const char kDirectiveElif[] = "elif";
+    const char kDirectiveEndif[] = "endif";
+    const char kDirectiveError[] = "error";
+    const char kDirectivePragma[] = "pragma";
+    const char kDirectiveExtension[] = "extension";
+    const char kDirectiveVersion[] = "version";
+    const char kDirectiveLine[] = "line";
 
     if (token->type != pp::Token::IDENTIFIER)
         return DIRECTIVE_NONE;
 
     if (token->text == kDirectiveDefine)
         return DIRECTIVE_DEFINE;
     if (token->text == kDirectiveUndef)
         return DIRECTIVE_UNDEF;
@@ -150,17 +150,17 @@ class DefinedParser : public Lexer
           mMacroSet(macroSet),
           mDiagnostics(diagnostics)
     {
     }
 
   protected:
     virtual void lex(Token *token)
     {
-        static const std::string kDefined("defined");
+        const char kDefined[] = "defined";
 
         mLexer->lex(token);
         if (token->type != Token::IDENTIFIER)
             return;
         if (token->text != kDefined)
             return;
 
         bool paren = false;
@@ -587,16 +587,21 @@ void DirectiveParser::parsePragma(Token 
         RIGHT_PAREN
     };
 
     bool valid = true;
     std::string name, value;
     int state = PRAGMA_NAME;
 
     mTokenizer->lex(token);
+    bool stdgl = token->text == "STDGL";
+    if (stdgl)
+    {
+        mTokenizer->lex(token);
+    }
     while ((token->type != '\n') && (token->type != Token::LAST))
     {
         switch(state++)
         {
           case PRAGMA_NAME:
             name = token->text;
             valid = valid && (token->type == Token::IDENTIFIER);
             break;
@@ -622,17 +627,17 @@ void DirectiveParser::parsePragma(Token 
                       (state == RIGHT_PAREN + 1));  // With value.
     if (!valid)
     {
         mDiagnostics->report(Diagnostics::PP_UNRECOGNIZED_PRAGMA,
                              token->location, name);
     }
     else if (state > PRAGMA_NAME)  // Do not notify for empty pragma.
     {
-        mDirectiveHandler->handlePragma(token->location, name, value);
+        mDirectiveHandler->handlePragma(token->location, name, value, stdgl);
     }
 }
 
 void DirectiveParser::parseExtension(Token *token)
 {
     assert(getDirective(token) == DIRECTIVE_EXTENSION);
 
     enum State
--- a/gfx/angle/src/compiler/preprocessor/MacroExpander.cpp
+++ b/gfx/angle/src/compiler/preprocessor/MacroExpander.cpp
@@ -189,18 +189,18 @@ bool MacroExpander::expandMacro(const Ma
     replacements->clear();
     if (macro.type == Macro::kTypeObj)
     {
         replacements->assign(macro.replacements.begin(),
                              macro.replacements.end());
 
         if (macro.predefined)
         {
-            static const std::string kLine = "__LINE__";
-            static const std::string kFile = "__FILE__";
+            const char kLine[] = "__LINE__";
+            const char kFile[] = "__FILE__";
 
             assert(replacements->size() == 1);
             Token& repl = replacements->front();
             if (macro.name == kLine)
             {
                 std::ostringstream stream;
                 stream << identifier.location.line;
                 repl.text = stream.str();
--- a/gfx/angle/src/compiler/translator/Compiler.cpp
+++ b/gfx/angle/src/compiler/translator/Compiler.cpp
@@ -24,34 +24,37 @@
 #include "compiler/translator/timing/RestrictFragmentShaderTiming.h"
 #include "compiler/translator/timing/RestrictVertexShaderTiming.h"
 #include "third_party/compiler/ArrayBoundsClamper.h"
 #include "angle_gl.h"
 #include "common/utilities.h"
 
 bool IsWebGLBasedSpec(ShShaderSpec spec)
 {
-     return spec == SH_WEBGL_SPEC || spec == SH_CSS_SHADERS_SPEC;
+    return (spec == SH_WEBGL_SPEC ||
+            spec == SH_CSS_SHADERS_SPEC ||
+            spec == SH_WEBGL2_SPEC);
 }
 
 size_t GetGlobalMaxTokenSize(ShShaderSpec spec)
 {
     // WebGL defines a max token legnth of 256, while ES2 leaves max token
     // size undefined. ES3 defines a max size of 1024 characters.
-    if (IsWebGLBasedSpec(spec))
+    switch (spec)
     {
+      case SH_WEBGL_SPEC:
+      case SH_CSS_SHADERS_SPEC:
         return 256;
-    }
-    else
-    {
+      default:
         return 1024;
     }
 }
 
 namespace {
+
 class TScopedPoolAllocator
 {
   public:
     TScopedPoolAllocator(TPoolAllocator* allocator) : mAllocator(allocator)
     {
         mAllocator->push();
         SetGlobalPoolAllocator(mAllocator);
     }
@@ -77,16 +80,34 @@ class TScopedSymbolTableLevel
     {
         while (!mTable->atBuiltInLevel())
             mTable->pop();
     }
 
   private:
     TSymbolTable* mTable;
 };
+
+int MapSpecToShaderVersion(ShShaderSpec spec)
+{
+    switch (spec)
+    {
+      case SH_GLES2_SPEC:
+      case SH_WEBGL_SPEC:
+      case SH_CSS_SHADERS_SPEC:
+        return 100;
+      case SH_GLES3_SPEC:
+      case SH_WEBGL2_SPEC:
+        return 300;
+      default:
+        UNREACHABLE();
+        return 0;
+    }
+}
+
 }  // namespace
 
 TShHandleBase::TShHandleBase()
 {
     allocator.push();
     SetGlobalPoolAllocator(&allocator);
 }
 
@@ -173,19 +194,31 @@ bool TCompiler::compile(const char* cons
     TScopedSymbolTableLevel scopedSymbolLevel(&symbolTable);
 
     // Parse shader.
     bool success =
         (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], NULL, &parseContext) == 0) &&
         (parseContext.treeRoot != NULL);
 
     shaderVersion = parseContext.getShaderVersion();
+    if (success && MapSpecToShaderVersion(shaderSpec) < shaderVersion)
+    {
+        infoSink.info.prefix(EPrefixError);
+        infoSink.info << "unsupported shader version";
+        success = false;
+    }
 
     if (success)
     {
+        mPragma = parseContext.pragma();
+        if (mPragma.stdgl.invariantAll)
+        {
+            symbolTable.setGlobalInvariant();
+        }
+
         TIntermNode* root = parseContext.treeRoot;
         success = intermediate.postProcess(root);
 
         // Disallow expressions deemed too complex.
         if (success && (compileOptions & SH_LIMIT_EXPRESSION_COMPLEXITY))
             success = limitExpressionComplexity(root);
 
         if (success)
@@ -373,17 +406,16 @@ void TCompiler::clearResults()
     infoSink.obj.erase();
     infoSink.debug.erase();
 
     attributes.clear();
     outputVariables.clear();
     uniforms.clear();
     expandedUniforms.clear();
     varyings.clear();
-    expandedVaryings.clear();
     interfaceBlocks.clear();
 
     builtInFunctionEmulator.Cleanup();
 
     nameMap.clear();
 }
 
 bool TCompiler::detectCallDepth(TIntermNode* root, TInfoSink& infoSink, bool limitCallStackDepth)
@@ -503,23 +535,22 @@ bool TCompiler::enforceVertexShaderTimin
 
 void TCompiler::collectVariables(TIntermNode* root)
 {
     sh::CollectVariables collect(&attributes,
                                  &outputVariables,
                                  &uniforms,
                                  &varyings,
                                  &interfaceBlocks,
-                                 hashFunction);
+                                 hashFunction,
+                                 symbolTable);
     root->traverse(&collect);
 
-    // For backwards compatiblity with ShGetVariableInfo, expand struct
-    // uniforms and varyings into separate variables for each field.
-    sh::ExpandVariables(uniforms, &expandedUniforms);
-    sh::ExpandVariables(varyings, &expandedVaryings);
+    // This is for enforcePackingRestriction().
+    sh::ExpandUniforms(uniforms, &expandedUniforms);
 }
 
 bool TCompiler::enforcePackingRestrictions()
 {
     VariablePacker packer;
     return packer.CheckVariablesWithinPackingLimits(maxUniformVectors, expandedUniforms);
 }
 
@@ -577,8 +608,15 @@ ShArrayIndexClampingStrategy TCompiler::
 {
     return clampingStrategy;
 }
 
 const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const
 {
     return builtInFunctionEmulator;
 }
+
+void TCompiler::writePragma()
+{
+    TInfoSinkBase &sink = infoSink.obj;
+    if (mPragma.stdgl.invariantAll)
+        sink << "#pragma STDGL invariant(all)\n";
+}
--- a/gfx/angle/src/compiler/translator/Compiler.h
+++ b/gfx/angle/src/compiler/translator/Compiler.h
@@ -13,16 +13,17 @@
 //
 // This should not be included by driver code.
 //
 
 #include "compiler/translator/BuiltInFunctionEmulator.h"
 #include "compiler/translator/ExtensionBehavior.h"
 #include "compiler/translator/HashNames.h"
 #include "compiler/translator/InfoSink.h"
+#include "compiler/translator/Pragma.h"
 #include "compiler/translator/SymbolTable.h"
 #include "compiler/translator/VariableInfo.h"
 #include "third_party/compiler/ArrayBoundsClamper.h"
 
 class TCompiler;
 class TDependencyGraph;
 class TranslatorHLSL;
 
@@ -66,27 +67,25 @@ class TCompiler : public TShHandleBase
 
     // Get results of the last compilation.
     int getShaderVersion() const { return shaderVersion; }
     TInfoSink& getInfoSink() { return infoSink; }
 
     const std::vector<sh::Attribute> &getAttributes() const { return attributes; }
     const std::vector<sh::Attribute> &getOutputVariables() const { return outputVariables; }
     const std::vector<sh::Uniform> &getUniforms() const { return uniforms; }
-    const std::vector<sh::ShaderVariable> &getExpandedUniforms() const { return expandedUniforms; }
     const std::vector<sh::Varying> &getVaryings() const { return varyings; }
-    const std::vector<sh::ShaderVariable> &getExpandedVaryings() const { return expandedVaryings; }
     const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const { return interfaceBlocks; }
 
     ShHashFunction64 getHashFunction() const { return hashFunction; }
     NameMap& getNameMap() { return nameMap; }
     TSymbolTable& getSymbolTable() { return symbolTable; }
     ShShaderSpec getShaderSpec() const { return shaderSpec; }
     ShShaderOutput getOutputType() const { return outputType; }
-    std::string getBuiltInResourcesString() const { return builtInResourcesString; }
+    const std::string &getBuiltInResourcesString() const { return builtInResourcesString; }
 
     // Get the resources set by InitBuiltInSymbolTable
     const ShBuiltInResources& getResources() const;
 
   protected:
     sh::GLenum getShaderType() const { return shaderType; }
     // Initialize symbol-table with built-in symbols.
     bool InitBuiltInSymbolTable(const ShBuiltInResources& resources);
@@ -126,27 +125,28 @@ class TCompiler : public TShHandleBase
     bool enforceVertexShaderTimingRestrictions(TIntermNode* root);
     // Returns true if the shader does not use sampler dependent values to affect control
     // flow or in operations whose time can depend on the input values.
     bool enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph);
     // Return true if the maximum expression complexity is below the limit.
     bool limitExpressionComplexity(TIntermNode* root);
     // Get built-in extensions with default behavior.
     const TExtensionBehavior& getExtensionBehavior() const;
+    const TPragma& getPragma() const { return mPragma; }
+    void writePragma();
 
     const ArrayBoundsClamper& getArrayBoundsClamper() const;
     ShArrayIndexClampingStrategy getArrayIndexClampingStrategy() const;
     const BuiltInFunctionEmulator& getBuiltInFunctionEmulator() const;
 
     std::vector<sh::Attribute> attributes;
     std::vector<sh::Attribute> outputVariables;
     std::vector<sh::Uniform> uniforms;
     std::vector<sh::ShaderVariable> expandedUniforms;
     std::vector<sh::Varying> varyings;
-    std::vector<sh::ShaderVariable> expandedVaryings;
     std::vector<sh::InterfaceBlock> interfaceBlocks;
 
   private:
     sh::GLenum shaderType;
     ShShaderSpec shaderSpec;
     ShShaderOutput outputType;
 
     int maxUniformVectors;
@@ -169,16 +169,18 @@ class TCompiler : public TShHandleBase
 
     // Results of compilation.
     int shaderVersion;
     TInfoSink infoSink;  // Output sink.
 
     // name hashing.
     ShHashFunction64 hashFunction;
     NameMap nameMap;
+
+    TPragma mPragma;
 };
 
 //
 // This is the interface between the machine independent code
 // and the machine dependent code.
 //
 // The machine dependent code should derive from the classes
 // above. Then Construct*() and Delete*() will create and
--- a/gfx/angle/src/compiler/translator/DirectiveHandler.cpp
+++ b/gfx/angle/src/compiler/translator/DirectiveHandler.cpp
@@ -8,20 +8,20 @@
 
 #include <sstream>
 
 #include "compiler/translator/compilerdebug.h"
 #include "compiler/translator/Diagnostics.h"
 
 static TBehavior getBehavior(const std::string& str)
 {
-    static const std::string kRequire("require");
-    static const std::string kEnable("enable");
-    static const std::string kDisable("disable");
-    static const std::string kWarn("warn");
+    const char kRequire[] = "require";
+    const char kEnable[] = "enable";
+    const char kDisable[] = "disable";
+    const char kWarn[] = "warn";
 
     if (str == kRequire) return EBhRequire;
     else if (str == kEnable) return EBhEnable;
     else if (str == kDisable) return EBhDisable;
     else if (str == kWarn) return EBhWarn;
     return EBhUndefined;
 }
 
@@ -41,60 +41,71 @@ TDirectiveHandler::~TDirectiveHandler()
 void TDirectiveHandler::handleError(const pp::SourceLocation& loc,
                                     const std::string& msg)
 {
     mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, msg, "", "");
 }
 
 void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc,
                                      const std::string& name,
-                                     const std::string& value)
+                                     const std::string& value,
+                                     bool stdgl)
 {
-    static const std::string kSTDGL("STDGL");
-    static const std::string kOptimize("optimize");
-    static const std::string kDebug("debug");
-    static const std::string kOn("on");
-    static const std::string kOff("off");
+    if (stdgl)
+    {
+        const char kInvariant[] = "invariant";
+        const char kAll[] = "all";
 
-    bool invalidValue = false;
-    if (name == kSTDGL)
-    {
+        if (name == kInvariant && value == kAll)
+            mPragma.stdgl.invariantAll = true;
         // The STDGL pragma is used to reserve pragmas for use by future
-        // revisions of GLSL. Ignore it.
+        // revisions of GLSL.  Do not generate an error on unexpected
+        // name and value.
         return;
     }
-    else if (name == kOptimize)
-    {
-        if (value == kOn) mPragma.optimize = true;
-        else if (value == kOff) mPragma.optimize = false;
-        else invalidValue = true;
-    }
-    else if (name == kDebug)
-    {
-        if (value == kOn) mPragma.debug = true;
-        else if (value == kOff) mPragma.debug = false;
-        else invalidValue = true;
-    }
     else
     {
-        mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
-        return;
-    }
+        const char kOptimize[] = "optimize";
+        const char kDebug[] = "debug";
+        const char kOn[] = "on";
+        const char kOff[] = "off";
 
-    if (invalidValue)
-      mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
-                             "invalid pragma value", value,
-                             "'on' or 'off' expected");
+        bool invalidValue = false;
+        if (name == kOptimize)
+        {
+            if (value == kOn) mPragma.optimize = true;
+            else if (value == kOff) mPragma.optimize = false;
+            else invalidValue = true;
+        }
+        else if (name == kDebug)
+        {
+            if (value == kOn) mPragma.debug = true;
+            else if (value == kOff) mPragma.debug = false;
+            else invalidValue = true;
+        }
+        else
+        {
+            mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
+            return;
+        }
+
+        if (invalidValue)
+        {
+            mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
+                                   "invalid pragma value", value,
+                                   "'on' or 'off' expected");
+        }
+    }
 }
 
 void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc,
                                         const std::string& name,
                                         const std::string& behavior)
 {
-    static const std::string kExtAll("all");
+    const char kExtAll[] = "all";
 
     TBehavior behaviorVal = getBehavior(behavior);
     if (behaviorVal == EBhUndefined)
     {
         mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
                                "behavior", name, "invalid");
         return;
     }
--- a/gfx/angle/src/compiler/translator/DirectiveHandler.h
+++ b/gfx/angle/src/compiler/translator/DirectiveHandler.h
@@ -24,17 +24,18 @@ class TDirectiveHandler : public pp::Dir
     const TPragma& pragma() const { return mPragma; }
     const TExtensionBehavior& extensionBehavior() const { return mExtensionBehavior; }
 
     virtual void handleError(const pp::SourceLocation& loc,
                              const std::string& msg);
 
     virtual void handlePragma(const pp::SourceLocation& loc,
                               const std::string& name,
-                              const std::string& value);
+                              const std::string& value,
+                              bool stdgl);
 
     virtual void handleExtension(const pp::SourceLocation& loc,
                                  const std::string& name,
                                  const std::string& behavior);
 
     virtual void handleVersion(const pp::SourceLocation& loc,
                                int version);
 
--- a/gfx/angle/src/compiler/translator/IntermNode.cpp
+++ b/gfx/angle/src/compiler/translator/IntermNode.cpp
@@ -128,16 +128,24 @@ bool CompareStructure(const TType &leftN
 
 
 ////////////////////////////////////////////////////////////////
 //
 // Member functions of the nodes used for building the tree.
 //
 ////////////////////////////////////////////////////////////////
 
+void TIntermTyped::setTypePreservePrecision(const TType &t)
+{
+    TPrecision precision = getPrecision();
+    mType = t;
+    ASSERT(mType.getBasicType() != EbtBool || precision == EbpUndefined);
+    mType.setPrecision(precision);
+}
+
 #define REPLACE_IF_IS(node, type, original, replacement) \
     if (node == original) { \
         node = static_cast<type *>(replacement); \
         return true; \
     }
 
 bool TIntermLoop::replaceChildNode(
     TIntermNode *original, TIntermNode *replacement)
@@ -232,16 +240,62 @@ bool TIntermAggregate::replaceChildNode(
 void TIntermAggregate::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
 {
     for (size_t childIndex = 0; childIndex < mSequence.size(); childIndex++)
     {
         nodeQueue->push(mSequence[childIndex]);
     }
 }
 
+void TIntermAggregate::setPrecisionFromChildren()
+{
+    if (getBasicType() == EbtBool)
+    {
+        mType.setPrecision(EbpUndefined);
+        return;
+    }
+
+    TPrecision precision = EbpUndefined;
+    TIntermSequence::iterator childIter = mSequence.begin();
+    while (childIter != mSequence.end())
+    {
+        TIntermTyped *typed = (*childIter)->getAsTyped();
+        if (typed)
+            precision = GetHigherPrecision(typed->getPrecision(), precision);
+        ++childIter;
+    }
+    mType.setPrecision(precision);
+}
+
+void TIntermAggregate::setBuiltInFunctionPrecision()
+{
+    // All built-ins returning bool should be handled as ops, not functions.
+    ASSERT(getBasicType() != EbtBool);
+
+    TPrecision precision = EbpUndefined;
+    TIntermSequence::iterator childIter = mSequence.begin();
+    while (childIter != mSequence.end())
+    {
+        TIntermTyped *typed = (*childIter)->getAsTyped();
+        // ESSL spec section 8: texture functions get their precision from the sampler.
+        if (typed && IsSampler(typed->getBasicType()))
+        {
+            precision = typed->getPrecision();
+            break;
+        }
+        ++childIter;
+    }
+    // ESSL 3.0 spec section 8: textureSize always gets highp precision.
+    // All other functions that take a sampler are assumed to be texture functions.
+    if (mName.find("textureSize") == 0)
+        mType.setPrecision(EbpHigh);
+    else
+        mType.setPrecision(precision);
+}
+
 bool TIntermSelection::replaceChildNode(
     TIntermNode *original, TIntermNode *replacement)
 {
     REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement);
     REPLACE_IF_IS(mTrueBlock, TIntermNode, original, replacement);
     REPLACE_IF_IS(mFalseBlock, TIntermNode, original, replacement);
     return false;
 }
@@ -331,16 +385,17 @@ bool TIntermUnary::promote(TInfoSink &)
 {
     switch (mOp)
     {
       case EOpLogicalNot:
         if (mOperand->getBasicType() != EbtBool)
             return false;
         break;
       case EOpNegative:
+      case EOpPositive:
       case EOpPostIncrement:
       case EOpPostDecrement:
       case EOpPreIncrement:
       case EOpPreDecrement:
         if (mOperand->getBasicType() == EbtBool)
             return false;
         break;
 
@@ -1063,16 +1118,37 @@ TIntermTyped *TIntermConstantUnion::fold
                   default:
                     infoSink.info.message(
                         EPrefixInternalError, getLine(),
                         "Unary operation not folded into constant");
                     return NULL;
                 }
                 break;
 
+              case EOpPositive:
+                switch (getType().getBasicType())
+                {
+                  case EbtFloat:
+                    tempConstArray[i].setFConst(unionArray[i].getFConst());
+                    break;
+                  case EbtInt:
+                    tempConstArray[i].setIConst(unionArray[i].getIConst());
+                    break;
+                  case EbtUInt:
+                    tempConstArray[i].setUConst(static_cast<unsigned int>(
+                        static_cast<int>(unionArray[i].getUConst())));
+                    break;
+                  default:
+                    infoSink.info.message(
+                        EPrefixInternalError, getLine(),
+                        "Unary operation not folded into constant");
+                    return NULL;
+                }
+                break;
+
               case EOpLogicalNot:
                 // this code is written for possible future use,
                 // will not get executed currently
                 switch (getType().getBasicType())
                 {
                   case EbtBool:
                     tempConstArray[i].setBConst(!unionArray[i].getBConst());
                     break;
--- a/gfx/angle/src/compiler/translator/IntermNode.h
+++ b/gfx/angle/src/compiler/translator/IntermNode.h
@@ -40,16 +40,17 @@ enum TOperator
     EOpInvariantDeclaration, // Specialized declarations for attributing invariance
     EOpPrototype,
 
     //
     // Unary operators
     //
 
     EOpNegative,
+    EOpPositive,
     EOpLogicalNot,
     EOpVectorLogicalNot,
 
     EOpPostIncrement,
     EOpPostDecrement,
     EOpPreIncrement,
     EOpPreDecrement,
 
@@ -260,16 +261,17 @@ class TIntermTyped : public TIntermNode
 {
   public:
     TIntermTyped(const TType &t) : mType(t)  { }
     virtual TIntermTyped *getAsTyped() { return this; }
 
     virtual bool hasSideEffects() const = 0;
 
     void setType(const TType &t) { mType = t; }
+    void setTypePreservePrecision(const TType &t);
     const TType &getType() const { return mType; }
     TType *getTypePointer() { return &mType; }
 
     TBasicType getBasicType() const { return mType.getBasicType(); }
     TQualifier getQualifier() const { return mType.getQualifier(); }
     TPrecision getPrecision() const { return mType.getPrecision(); }
     int getCols() const { return mType.getCols(); }
     int getRows() const { return mType.getRows(); }
@@ -608,16 +610,19 @@ class TIntermAggregate : public TIntermO
     void setDebug(bool debug) { mDebug = debug; }
     bool getDebug() const { return mDebug; }
 
     void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
     bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
 
     virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
 
+    void setPrecisionFromChildren();
+    void setBuiltInFunctionPrecision();
+
   protected:
     TIntermAggregate(const TIntermAggregate &); // disallow copy constructor
     TIntermAggregate &operator=(const TIntermAggregate &); // disallow assignment operator
     TIntermSequence mSequence;
     TString mName;
     bool mUserDefined; // used for user defined function names
 
     bool mOptimize;
--- a/gfx/angle/src/compiler/translator/Intermediate.cpp
+++ b/gfx/angle/src/compiler/translator/Intermediate.cpp
@@ -193,16 +193,17 @@ TIntermTyped *TIntermediate::addUnaryMat
         }
         break;
 
       case EOpPostIncrement:
       case EOpPreIncrement:
       case EOpPostDecrement:
       case EOpPreDecrement:
       case EOpNegative:
+      case EOpPositive:
         if (child->getType().getBasicType() == EbtStruct ||
             child->getType().isArray())
         {
             return NULL;
         }
       default:
         break;
     }
--- a/gfx/angle/src/compiler/translator/OutputGLSLBase.cpp
+++ b/gfx/angle/src/compiler/translator/OutputGLSLBase.cpp
@@ -390,16 +390,17 @@ bool TOutputGLSLBase::visitBinary(Visit 
 bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary *node)
 {
     TString preString;
     TString postString = ")";
 
     switch (node->getOp())
     {
       case EOpNegative: preString = "(-"; break;
+      case EOpPositive: preString = "(+"; break;
       case EOpVectorLogicalNot: preString = "not("; break;
       case EOpLogicalNot: preString = "(!"; break;
 
       case EOpPostIncrement: preString = "("; postString = "++)"; break;
       case EOpPostDecrement: preString = "("; postString = "--)"; break;
       case EOpPreIncrement: preString = "(++"; break;
       case EOpPreDecrement: preString = "(--"; break;
 
@@ -644,27 +645,28 @@ bool TOutputGLSLBase::visitAggregate(Vis
             out << ", ";
             mDeclaringVariables = true;
         }
         else
         {
             mDeclaringVariables = false;
         }
         break;
-      case EOpInvariantDeclaration: {
-            // Invariant declaration.
-            ASSERT(visit == PreVisit);
+      case EOpInvariantDeclaration:
+        // Invariant declaration.
+        ASSERT(visit == PreVisit);
+        {
             const TIntermSequence *sequence = node->getSequence();
             ASSERT(sequence && sequence->size() == 1);
             const TIntermSymbol *symbol = sequence->front()->getAsSymbolNode();
             ASSERT(symbol);
-            out << "invariant " << symbol->getSymbol() << ";";
-            visitChildren = false;
-            break;
+            out << "invariant " << hashVariableName(symbol->getSymbol());
         }
+        visitChildren = false;
+        break;
       case EOpConstructFloat:
         writeTriplet(visit, "float(", NULL, ")");
         break;
       case EOpConstructVec2:
         writeBuiltInFunctionTriplet(visit, "vec2(", false);
         break;
       case EOpConstructVec3:
         writeBuiltInFunctionTriplet(visit, "vec3(", false);
@@ -736,17 +738,17 @@ bool TOutputGLSLBase::visitAggregate(Vis
         break;
       case EOpVectorEqual:
         writeBuiltInFunctionTriplet(visit, "equal(", useEmulatedFunction);
         break;
       case EOpVectorNotEqual:
         writeBuiltInFunctionTriplet(visit, "notEqual(", useEmulatedFunction);
         break;
       case EOpComma:
-        writeTriplet(visit, NULL, ", ", NULL);
+        writeTriplet(visit, "(", ", ", ")");
         break;
 
       case EOpMod:
         writeBuiltInFunctionTriplet(visit, "mod(", useEmulatedFunction);
         break;
       case EOpPow:
         writeBuiltInFunctionTriplet(visit, "pow(", useEmulatedFunction);
         break;
--- a/gfx/angle/src/compiler/translator/OutputHLSL.cpp
+++ b/gfx/angle/src/compiler/translator/OutputHLSL.cpp
@@ -315,24 +315,32 @@ void OutputHLSL::header()
 
     out << mStructureHLSL->structsHeader();
 
     out << mUniformHLSL->uniformsHeader(mOutputType, mReferencedUniforms);
     out << mUniformHLSL->interfaceBlocksHeader(mReferencedInterfaceBlocks);
 
     if (mUsesDiscardRewriting)
     {
-        out << "#define ANGLE_USES_DISCARD_REWRITING" << "\n";
+        out << "#define ANGLE_USES_DISCARD_REWRITING\n";
     }
 
     if (mUsesNestedBreak)
     {
-        out << "#define ANGLE_USES_NESTED_BREAK" << "\n";
+        out << "#define ANGLE_USES_NESTED_BREAK\n";
     }
 
+    out << "#ifdef ANGLE_ENABLE_LOOP_FLATTEN\n"
+           "#define LOOP [loop]\n"
+           "#define FLATTEN [flatten]\n"
+           "#else\n"
+           "#define LOOP\n"
+           "#define FLATTEN\n"
+           "#endif\n";
+
     if (mContext.shaderType == GL_FRAGMENT_SHADER)
     {
         TExtensionBehavior::const_iterator iter = mContext.extensionBehavior().find("GL_EXT_draw_buffers");
         const bool usingMRTExtension = (iter != mContext.extensionBehavior().end() && (iter->second == EBhEnable || iter->second == EBhRequire));
 
         out << "// Varyings\n";
         out <<  varyings;
         out << "\n";
@@ -1742,16 +1750,17 @@ bool OutputHLSL::visitBinary(Visit visit
     return true;
 }
 
 bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
 {
     switch (node->getOp())
     {
       case EOpNegative:         outputTriplet(visit, "(-", "", ")");         break;
+      case EOpPositive:         outputTriplet(visit, "(+", "", ")");         break;
       case EOpVectorLogicalNot: outputTriplet(visit, "(!", "", ")");         break;
       case EOpLogicalNot:       outputTriplet(visit, "(!", "", ")");         break;
       case EOpPostIncrement:    outputTriplet(visit, "(", "", "++)");        break;
       case EOpPostDecrement:    outputTriplet(visit, "(", "", "--)");        break;
       case EOpPreIncrement:     outputTriplet(visit, "(++", "", ")");        break;
       case EOpPreDecrement:     outputTriplet(visit, "(--", "", ")");        break;
       case EOpRadians:          outputTriplet(visit, "radians(", "", ")");   break;
       case EOpDegrees:          outputTriplet(visit, "degrees(", "", ")");   break;
@@ -1855,41 +1864,46 @@ bool OutputHLSL::visitAggregate(Visit vi
 
                 if (structure)
                 {
                     mStructureHLSL->addConstructor(variable->getType(), StructNameString(*structure), NULL);
                 }
 
                 if (!variable->getAsSymbolNode() || variable->getAsSymbolNode()->getSymbol() != "")   // Variable declaration
                 {
-                    if (!mInsideFunction)
-                    {
-                        out << "static ";
-                    }
-
-                    out << TypeString(variable->getType()) + " ";
-
                     for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); sit++)
                     {
+                        if (isSingleStatement(*sit))
+                        {
+                            mUnfoldShortCircuit->traverse(*sit);
+                        }
+
+                        if (!mInsideFunction)
+                        {
+                            out << "static ";
+                        }
+
+                        out << TypeString(variable->getType()) + " ";
+
                         TIntermSymbol *symbol = (*sit)->getAsSymbolNode();
 
                         if (symbol)
                         {
                             symbol->traverse(this);
                             out << ArrayString(symbol->getType());
                             out << " = " + initializer(symbol->getType());
                         }
                         else
                         {
                             (*sit)->traverse(this);
                         }
 
                         if (*sit != sequence->back())
                         {
-                            out << ", ";
+                            out << ";\n";
                         }
                     }
                 }
                 else if (variable->getAsSymbolNode() && variable->getAsSymbolNode()->getSymbol() == "")   // Type (struct) declaration
                 {
                     // Already added to constructor map
                 }
                 else UNREACHABLE();
@@ -2282,17 +2296,17 @@ bool OutputHLSL::visitSelection(Visit vi
     if (node->usesTernaryOperator())
     {
         out << "s" << mUnfoldShortCircuit->getNextTemporaryIndex();
     }
     else  // if/else statement
     {
         mUnfoldShortCircuit->traverse(node->getCondition());
 
-        out << "if (";
+        out << "FLATTEN if (";
 
         node->getCondition()->traverse(this);
 
         out << ")\n";
 
         outputLineDirective(node->getLine().first_line);
         out << "{\n";
 
@@ -2362,24 +2376,24 @@ bool OutputHLSL::visitLoop(Visit visit, 
             return false;
         }
     }
 
     TInfoSinkBase &out = mBody;
 
     if (node->getType() == ELoopDoWhile)
     {
-        out << "{do\n";
+        out << "{LOOP do\n";
 
         outputLineDirective(node->getLine().first_line);
         out << "{\n";
     }
     else
     {
-        out << "{for(";
+        out << "{LOOP for(";
 
         if (node->getInit())
         {
             node->getInit()->traverse(this);
         }
 
         out << "; ";
 
@@ -2498,16 +2512,22 @@ bool OutputHLSL::isSingleStatement(TInte
     TIntermAggregate *aggregate = node->getAsAggregate();
 
     if (aggregate)
     {
         if (aggregate->getOp() == EOpSequence)
         {
             return false;
         }
+        else if (aggregate->getOp() == EOpDeclaration)
+        {
+            // Declaring multiple comma-separated variables must be considered multiple statements
+            // because each individual declaration has side effects which are visible in the next.
+            return false;
+        }
         else
         {
             for (TIntermSequence::iterator sit = aggregate->getSequence()->begin(); sit != aggregate->getSequence()->end(); sit++)
             {
                 if (!isSingleStatement(*sit))
                 {
                     return false;
                 }
@@ -2670,17 +2690,17 @@ bool OutputHLSL::handleExcessiveLoop(TIn
 
                 if (iterations <= MAX_LOOP_ITERATIONS)   // Last loop fragment
                 {
                     mExcessiveLoopIndex = NULL;   // Stops setting the Break flag
                 }
 
                 // for(int index = initial; index < clampedLimit; index += increment)
 
-                out << "for(";
+                out << "LOOP for(";
                 index->traverse(this);
                 out << " = ";
                 out << initial;
 
                 out << "; ";
                 index->traverse(this);
                 out << " < ";
                 out << clampedLimit;
--- a/gfx/angle/src/compiler/translator/ParseContext.cpp
+++ b/gfx/angle/src/compiler/translator/ParseContext.cpp
@@ -999,22 +999,22 @@ bool TParseContext::isExtensionEnabled(c
 void TParseContext::handleExtensionDirective(const TSourceLoc& loc, const char* extName, const char* behavior)
 {
     pp::SourceLocation srcLoc;
     srcLoc.file = loc.first_file;
     srcLoc.line = loc.first_line;
     directiveHandler.handleExtension(srcLoc, extName, behavior);
 }
 
-void TParseContext::handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value)
+void TParseContext::handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value, bool stdgl)
 {
     pp::SourceLocation srcLoc;
     srcLoc.file = loc.first_file;
     srcLoc.line = loc.first_line;
-    directiveHandler.handlePragma(srcLoc, name, value);
+    directiveHandler.handlePragma(srcLoc, name, value, stdgl);
 }
 
 /////////////////////////////////////////////////////////////////////////////////
 //
 // Non-Errors.
 //
 /////////////////////////////////////////////////////////////////////////////////
 
@@ -1359,21 +1359,28 @@ TIntermAggregate* TParseContext::parseIn
     {
         recover();
     }
 
     if (!symbol)
     {
         error(identifierLoc, "undeclared identifier declared as invariant", identifier->c_str());
         recover();
-
         return NULL;
     }
     else
     {
+        const TString kGlFrontFacing("gl_FrontFacing");
+        if (*identifier == kGlFrontFacing)
+        {
+            error(identifierLoc, "identifier should not be declared as invariant", identifier->c_str());
+            recover();
+            return NULL;
+        }
+        symbolTable.addInvariantVarying(std::string(identifier->c_str()));
         const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol);
         ASSERT(variable);
         const TType &type = variable->getType();
         TIntermSymbol *intermSymbol = intermediate.addSymbol(variable->getUniqueId(),
                                                              *identifier, type, identifierLoc);
 
         TIntermAggregate *aggregate = intermediate.makeAggregate(intermSymbol, identifierLoc);
         aggregate->setOp(EOpInvariantDeclaration);
--- a/gfx/angle/src/compiler/translator/ParseContext.h
+++ b/gfx/angle/src/compiler/translator/ParseContext.h
@@ -111,17 +111,17 @@ struct TParseContext {
     bool singleDeclarationErrorCheck(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier);
     bool layoutLocationErrorCheck(const TSourceLoc& location, const TLayoutQualifier &layoutQualifier);
 
     const TPragma& pragma() const { return directiveHandler.pragma(); }
     const TExtensionBehavior& extensionBehavior() const { return directiveHandler.extensionBehavior(); }
     bool supportsExtension(const char* extension);
     bool isExtensionEnabled(const char* extension) const;
     void handleExtensionDirective(const TSourceLoc& loc, const char* extName, const char* behavior);
-    void handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value);
+    void handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value, bool stdgl);
 
     bool containsSampler(TType& type);
     bool areAllChildConst(TIntermAggregate* aggrNode);
     const TFunction* findFunction(const TSourceLoc& line, TFunction* pfnCall, int shaderVersion, bool *builtIn = 0);
     bool executeInitializer(const TSourceLoc& line, const TString& identifier, TPublicType& pType,
                             TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0);
 
     TPublicType addFullySpecifiedType(TQualifier qualifier, const TPublicType& typeSpecifier);
--- a/gfx/angle/src/compiler/translator/Pragma.h
+++ b/gfx/angle/src/compiler/translator/Pragma.h
@@ -2,18 +2,28 @@
 // Copyright (c) 2012 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_PRAGMA_H_
 #define COMPILER_PRAGMA_H_
 
-struct TPragma {
+struct TPragma
+{
+    struct STDGL
+    {
+        STDGL() : invariantAll(false) { }
+
+        bool invariantAll;
+    };
+
+
     // By default optimization is turned on and debug is turned off.
     TPragma() : optimize(true), debug(false) { }
     TPragma(bool o, bool d) : optimize(o), debug(d) { }
 
     bool optimize;
     bool debug;
+    STDGL stdgl;
 };
 
 #endif // COMPILER_PRAGMA_H_
--- a/gfx/angle/src/compiler/translator/ShaderLang.cpp
+++ b/gfx/angle/src/compiler/translator/ShaderLang.cpp
@@ -32,82 +32,16 @@ enum ShaderVariableType
     
 bool isInitialized = false;
 
 //
 // This is the platform independent interface between an OGL driver
 // and the shading language compiler.
 //
 
-static bool CheckVariableMaxLengths(const ShHandle handle,
-                                    size_t expectedValue)
-{
-    size_t activeUniformLimit = 0;
-    ShGetInfo(handle, SH_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformLimit);
-    size_t activeAttribLimit = 0;
-    ShGetInfo(handle, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &activeAttribLimit);
-    size_t varyingLimit = 0;
-    ShGetInfo(handle, SH_VARYING_MAX_LENGTH, &varyingLimit);
-    return (expectedValue == activeUniformLimit &&
-            expectedValue == activeAttribLimit &&
-            expectedValue == varyingLimit);
-}
-
-bool CheckMappedNameMaxLength(const ShHandle handle, size_t expectedValue)
-{
-    size_t mappedNameMaxLength = 0;
-    ShGetInfo(handle, SH_MAPPED_NAME_MAX_LENGTH, &mappedNameMaxLength);
-    return (expectedValue == mappedNameMaxLength);
-}
-
-template <typename VarT>
-const sh::ShaderVariable *ReturnVariable(const std::vector<VarT> &infoList, int index)
-{
-    if (index < 0 || static_cast<size_t>(index) >= infoList.size())
-    {
-        return NULL;
-    }
-
-    return &infoList[index];
-}
-
-const sh::ShaderVariable *GetVariable(const TCompiler *compiler, ShShaderInfo varType, int index)
-{
-    switch (varType)
-    {
-      case SH_ACTIVE_ATTRIBUTES:
-        return ReturnVariable(compiler->getAttributes(), index);
-      case SH_ACTIVE_UNIFORMS:
-        return ReturnVariable(compiler->getExpandedUniforms(), index);
-      case SH_VARYINGS:
-        return ReturnVariable(compiler->getExpandedVaryings(), index);
-      default:
-        UNREACHABLE();
-        return NULL;
-    }
-}
-
-ShPrecisionType ConvertPrecision(sh::GLenum precision)
-{
-    switch (precision)
-    {
-      case GL_HIGH_FLOAT:
-      case GL_HIGH_INT:
-        return SH_PRECISION_HIGHP;
-      case GL_MEDIUM_FLOAT:
-      case GL_MEDIUM_INT:
-        return SH_PRECISION_MEDIUMP;
-      case GL_LOW_FLOAT:
-      case GL_LOW_INT:
-        return SH_PRECISION_LOWP;
-      default:
-        return SH_PRECISION_UNDEFINED;
-    }
-}
-
 template <typename VarT>
 const std::vector<VarT> *GetVariableList(const TCompiler *compiler, ShaderVariableType variableType);
 
 template <>
 const std::vector<sh::Uniform> *GetVariableList(const TCompiler *compiler, ShaderVariableType)
 {
     return &compiler->getUniforms();
 }
@@ -145,49 +79,68 @@ const std::vector<VarT> *GetShaderVariab
     if (!compiler)
     {
         return NULL;
     }
 
     return GetVariableList<VarT>(compiler, variableType);
 }
 
+TCompiler *GetCompilerFromHandle(ShHandle handle)
+{
+    if (!handle)
+        return NULL;
+    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+    return base->getAsCompiler();
 }
 
+TranslatorHLSL *GetTranslatorHLSLFromHandle(ShHandle handle)
+{
+    if (!handle)
+        return NULL;
+    TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+    return base->getAsTranslatorHLSL();
+}
+
+}  // namespace anonymous
+
 //
 // Driver must call this first, once, before doing any other compiler operations.
 // Subsequent calls to this function are no-op.
 //
-int ShInitialize()
+bool ShInitialize()
 {
     if (!isInitialized)
     {
         isInitialized = InitProcess();
     }
-    return isInitialized ? 1 : 0;
+    return isInitialized;
 }
 
 //
 // Cleanup symbol tables
 //
-int ShFinalize()
+bool ShFinalize()
 {
     if (isInitialized)
     {
         DetachProcess();
         isInitialized = false;
     }
-    return 1;
+    return true;
 }
 
 //
 // Initialize built-in resources with minimum expected values.
 //
 void ShInitBuiltInResources(ShBuiltInResources* resources)
 {
+    // Make comparable.
+    memset(resources, 0, sizeof(*resources));
+
     // Constants.
     resources->MaxVertexAttribs = 8;
     resources->MaxVertexUniformVectors = 128;
     resources->MaxVaryingVectors = 8;
     resources->MaxVertexTextureImageUnits = 0;
     resources->MaxCombinedTextureImageUnits = 8;
     resources->MaxTextureImageUnits = 8;
     resources->MaxFragmentUniformVectors = 16;
@@ -248,253 +201,86 @@ void ShDestruct(ShHandle handle)
         return;
 
     TShHandleBase* base = static_cast<TShHandleBase*>(handle);
 
     if (base->getAsCompiler())
         DeleteCompiler(base->getAsCompiler());
 }
 
-void ShGetBuiltInResourcesString(const ShHandle handle, size_t outStringLen, char *outString)
+const std::string &ShGetBuiltInResourcesString(const ShHandle handle)
 {
-    if (!handle || !outString)
-    {
-        return;
-    }
+    TCompiler *compiler = GetCompilerFromHandle(handle);
+    ASSERT(compiler);
+    return compiler->getBuiltInResourcesString();
+}
 
-    TShHandleBase *base = static_cast<TShHandleBase*>(handle);
-    TCompiler *compiler = base->getAsCompiler();
-    if (!compiler)
-    {
-        return;
-    }
-
-    strncpy(outString, compiler->getBuiltInResourcesString().c_str(), outStringLen);
-    outString[outStringLen - 1] = '\0';
-}
 //
 // Do an actual compile on the given strings.  The result is left
 // in the given compile object.
 //
 // Return:  The return value of ShCompile is really boolean, indicating
 // success or failure.
 //
-int ShCompile(
+bool ShCompile(
     const ShHandle handle,
-    const char* const shaderStrings[],
+    const char *const shaderStrings[],
     size_t numStrings,
     int compileOptions)
 {
-    if (handle == 0)
-        return 0;
+    TCompiler *compiler = GetCompilerFromHandle(handle);
+    ASSERT(compiler);
 
-    TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
-    TCompiler* compiler = base->getAsCompiler();
-    if (compiler == 0)
-        return 0;
-
-    bool success = compiler->compile(shaderStrings, numStrings, compileOptions);
-    return success ? 1 : 0;
+    return compiler->compile(shaderStrings, numStrings, compileOptions);
 }
 
-void ShGetInfo(const ShHandle handle, ShShaderInfo pname, size_t* params)
+int ShGetShaderVersion(const ShHandle handle)
 {
-    if (!handle || !params)
-        return;
-
-    TShHandleBase* base = static_cast<TShHandleBase*>(handle);
-    TCompiler* compiler = base->getAsCompiler();
-    if (!compiler) return;
+    TCompiler* compiler = GetCompilerFromHandle(handle);
+    ASSERT(compiler);
+    return compiler->getShaderVersion();
+}
 
-    switch(pname)
-    {
-    case SH_INFO_LOG_LENGTH:
-        *params = compiler->getInfoSink().info.size() + 1;
-        break;
-    case SH_OBJECT_CODE_LENGTH:
-        *params = compiler->getInfoSink().obj.size() + 1;
-        break;
-    case SH_ACTIVE_UNIFORMS:
-        *params = compiler->getExpandedUniforms().size();
-        break;
-    case SH_ACTIVE_UNIFORM_MAX_LENGTH:
-        *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
-        break;
-    case SH_ACTIVE_ATTRIBUTES:
-        *params = compiler->getAttributes().size();
-        break;
-    case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
-        *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
-        break;
-    case SH_VARYINGS:
-        *params = compiler->getExpandedVaryings().size();
-        break;
-    case SH_VARYING_MAX_LENGTH:
-        *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
-        break;
-    case SH_MAPPED_NAME_MAX_LENGTH:
-        // Use longer length than MAX_SHORTENED_IDENTIFIER_SIZE to
-        // handle array and struct dereferences.
-        *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
-        break;
-    case SH_NAME_MAX_LENGTH:
-        *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
-        break;
-    case SH_HASHED_NAME_MAX_LENGTH:
-        if (compiler->getHashFunction() == NULL) {
-            *params = 0;
-        } else {
-            // 64 bits hashing output requires 16 bytes for hex 
-            // representation.
-            const char HashedNamePrefix[] = HASHED_NAME_PREFIX;
-            (void)HashedNamePrefix;
-            *params = 16 + sizeof(HashedNamePrefix);
-        }
-        break;
-    case SH_HASHED_NAMES_COUNT:
-        *params = compiler->getNameMap().size();
-        break;
-    case SH_SHADER_VERSION:
-        *params = compiler->getShaderVersion();
-        break;
-    case SH_RESOURCES_STRING_LENGTH:
-        *params = compiler->getBuiltInResourcesString().length() + 1;
-        break;
-    case SH_OUTPUT_TYPE:
-        *params = compiler->getOutputType();
-        break;
-    default: UNREACHABLE();
-    }
+ShShaderOutput ShGetShaderOutputType(const ShHandle handle)
+{
+    TCompiler* compiler = GetCompilerFromHandle(handle);
+    ASSERT(compiler);
+    return compiler->getOutputType();
 }
 
 //
 // Return any compiler log of messages for the application.
 //
-void ShGetInfoLog(const ShHandle handle, char* infoLog)
+const std::string &ShGetInfoLog(const ShHandle handle)
 {
-    if (!handle || !infoLog)
-        return;
+    TCompiler *compiler = GetCompilerFromHandle(handle);
+    ASSERT(compiler);
 
-    TShHandleBase* base = static_cast<TShHandleBase*>(handle);
-    TCompiler* compiler = base->getAsCompiler();
-    if (!compiler) return;
-
-    TInfoSink& infoSink = compiler->getInfoSink();
-    strcpy(infoLog, infoSink.info.c_str());
+    TInfoSink &infoSink = compiler->getInfoSink();
+    return infoSink.info.str();
 }
 
 //
 // Return any object code.
 //
-void ShGetObjectCode(const ShHandle handle, char* objCode)
+const std::string &ShGetObjectCode(const ShHandle handle)
 {
-    if (!handle || !objCode)
-        return;
+    TCompiler *compiler = GetCompilerFromHandle(handle);
+    ASSERT(compiler);
 
-    TShHandleBase* base = static_cast<TShHandleBase*>(handle);
-    TCompiler* compiler = base->getAsCompiler();
-    if (!compiler) return;
-
-    TInfoSink& infoSink = compiler->getInfoSink();
-    strcpy(objCode, infoSink.obj.c_str());
+    TInfoSink &infoSink = compiler->getInfoSink();
+    return infoSink.obj.str();
 }
 
-void ShGetVariableInfo(const ShHandle handle,
-                       ShShaderInfo varType,
-                       int index,
-                       size_t* length,
-                       int* size,
-                       sh::GLenum* type,
-                       ShPrecisionType* precision,
-                       int* staticUse,
-                       char* name,
-                       char* mappedName)
+const std::map<std::string, std::string> *ShGetNameHashingMap(
+    const ShHandle handle)
 {
-    if (!handle || !size || !type || !precision || !staticUse || !name)
-        return;
-    ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
-           (varType == SH_ACTIVE_UNIFORMS) ||
-           (varType == SH_VARYINGS));
-
-    TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
-    TCompiler* compiler = base->getAsCompiler();
-    if (compiler == 0)
-        return;
-
-    const sh::ShaderVariable *varInfo = GetVariable(compiler, varType, index);
-    if (!varInfo)
-    {
-        return;
-    }
-
-    if (length) *length = varInfo->name.size();
-    *size = varInfo->elementCount();
-    *type = varInfo->type;
-    *precision = ConvertPrecision(varInfo->precision);
-    *staticUse = varInfo->staticUse ? 1 : 0;
-
-    // This size must match that queried by
-    // SH_ACTIVE_UNIFORM_MAX_LENGTH, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, SH_VARYING_MAX_LENGTH
-    // in ShGetInfo, below.
-    size_t variableLength = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
-    ASSERT(CheckVariableMaxLengths(handle, variableLength));
-    strncpy(name, varInfo->name.c_str(), variableLength);
-    name[variableLength - 1] = 0;
-    if (mappedName)
-    {
-        // This size must match that queried by
-        // SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below.
-        size_t maxMappedNameLength = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
-        ASSERT(CheckMappedNameMaxLength(handle, maxMappedNameLength));
-        strncpy(mappedName, varInfo->mappedName.c_str(), maxMappedNameLength);
-        mappedName[maxMappedNameLength - 1] = 0;
-    }
-}
-
-void ShGetNameHashingEntry(const ShHandle handle,
-                           int index,
-                           char* name,
-                           char* hashedName)
-{
-    if (!handle || !name || !hashedName || index < 0)
-        return;
-
-    TShHandleBase* base = static_cast<TShHandleBase*>(handle);
-    TCompiler* compiler = base->getAsCompiler();
-    if (!compiler) return;
-
-    const NameMap& nameMap = compiler->getNameMap();
-    if (index >= static_cast<int>(nameMap.size()))
-        return;
-
-    NameMap::const_iterator it = nameMap.begin();
-    for (int i = 0; i < index; ++i)
-        ++it;
-
-    size_t len = it->first.length() + 1;
-    size_t max_len = 0;
-    ShGetInfo(handle, SH_NAME_MAX_LENGTH, &max_len);
-    if (len > max_len) {
-        ASSERT(false);
-        len = max_len;
-    }
-    strncpy(name, it->first.c_str(), len);
-    // To be on the safe side in case the source is longer than expected.
-    name[len - 1] = '\0';
-
-    len = it->second.length() + 1;
-    max_len = 0;
-    ShGetInfo(handle, SH_HASHED_NAME_MAX_LENGTH, &max_len);
-    if (len > max_len) {
-        ASSERT(false);
-        len = max_len;
-    }
-    strncpy(hashedName, it->second.c_str(), len);
-    // To be on the safe side in case the source is longer than expected.
-    hashedName[len - 1] = '\0';
+    TCompiler *compiler = GetCompilerFromHandle(handle);
+    ASSERT(compiler);
+    return &(compiler->getNameMap());
 }
 
 const std::vector<sh::Uniform> *ShGetUniforms(const ShHandle handle)
 {
     return GetShaderVariables<sh::Uniform>(handle, SHADERVAR_UNIFORM);
 }
 
 const std::vector<sh::Varying> *ShGetVaryings(const ShHandle handle)
@@ -512,72 +298,57 @@ const std::vector<sh::Attribute> *ShGetO
     return GetShaderVariables<sh::Attribute>(handle, SHADERVAR_OUTPUTVARIABLE);
 }
 
 const std::vector<sh::InterfaceBlock> *ShGetInterfaceBlocks(const ShHandle handle)
 {
     return GetShaderVariables<sh::InterfaceBlock>(handle, SHADERVAR_INTERFACEBLOCK);
 }
 
-int ShCheckVariablesWithinPackingLimits(
-    int maxVectors, ShVariableInfo* varInfoArray, size_t varInfoArraySize)
+bool ShCheckVariablesWithinPackingLimits(
+    int maxVectors, ShVariableInfo *varInfoArray, size_t varInfoArraySize)
 {
     if (varInfoArraySize == 0)
-        return 1;
+        return true;
     ASSERT(varInfoArray);
     std::vector<sh::ShaderVariable> variables;
     for (size_t ii = 0; ii < varInfoArraySize; ++ii)
     {
         sh::ShaderVariable var(varInfoArray[ii].type, varInfoArray[ii].size);
         variables.push_back(var);
     }
     VariablePacker packer;
-    return packer.CheckVariablesWithinPackingLimits(maxVectors, variables) ? 1 : 0;
+    return packer.CheckVariablesWithinPackingLimits(maxVectors, variables);
 }
 
 bool ShGetInterfaceBlockRegister(const ShHandle handle,
-                                 const char *interfaceBlockName,
+                                 const std::string &interfaceBlockName,
                                  unsigned int *indexOut)
 {
-    if (!handle || !interfaceBlockName || !indexOut)
-    {
-        return false;
-    }
+    ASSERT(indexOut);
 
-    TShHandleBase* base = static_cast<TShHandleBase*>(handle);
-    TranslatorHLSL* translator = base->getAsTranslatorHLSL();
-    if (!translator)
-    {
-        return false;
-    }
+    TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
+    ASSERT(translator);
 
     if (!translator->hasInterfaceBlock(interfaceBlockName))
     {
         return false;
     }
 
     *indexOut = translator->getInterfaceBlockRegister(interfaceBlockName);
     return true;
 }
 
 bool ShGetUniformRegister(const ShHandle handle,
-                          const char *uniformName,
+                          const std::string &uniformName,
                           unsigned int *indexOut)
 {
-    if (!handle || !uniformName || !indexOut)
-    {
-        return false;
-    }
-
-    TShHandleBase* base = static_cast<TShHandleBase*>(handle);
-    TranslatorHLSL* translator = base->getAsTranslatorHLSL();
-    if (!translator)
-    {
-        return false;
-    }
+    ASSERT(indexOut);
+    TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
+    ASSERT(translator);
 
     if (!translator->hasUniform(uniformName))
     {
         return false;
     }
 
     *indexOut = translator->getUniformRegister(uniformName);
     return true;
--- a/gfx/angle/src/compiler/translator/SymbolTable.h
+++ b/gfx/angle/src/compiler/translator/SymbolTable.h
@@ -26,16 +26,17 @@
 //   in the symbol table.  The parser can substitute constants at parse
 //   time, including doing constant folding and constant propagation.
 //
 // * No temporaries:  Temporaries made from operations (+, --, .xy, etc.)
 //   are tracked in the intermediate representation, not the symbol table.
 //
 
 #include <assert.h>
+#include <set>
 
 #include "common/angleutils.h"
 #include "compiler/translator/InfoSink.h"
 #include "compiler/translator/IntermNode.h"
 
 // Symbol base class. (Can build functions or variables out of these...)
 class TSymbol
 {
@@ -294,29 +295,31 @@ class TSymbolTableLevel
 
     void relateToOperator(const char *name, TOperator op);
     void relateToExtension(const char *name, const TString &ext);
 
   protected:
     tLevel level;
 };
 
-enum ESymbolLevel
-{
-    COMMON_BUILTINS = 0,
-    ESSL1_BUILTINS = 1,
-    ESSL3_BUILTINS = 2,
-    LAST_BUILTIN_LEVEL = ESSL3_BUILTINS,
-    GLOBAL_LEVEL = 3
-};
+// Define ESymbolLevel as int rather than an enum since level can go
+// above GLOBAL_LEVEL and cause atBuiltInLevel() to fail if the
+// compiler optimizes the >= of the last element to ==.
+typedef int ESymbolLevel;
+const int COMMON_BUILTINS = 0;
+const int ESSL1_BUILTINS = 1;
+const int ESSL3_BUILTINS = 2;
+const int LAST_BUILTIN_LEVEL = ESSL3_BUILTINS;
+const int GLOBAL_LEVEL = 3;
 
 class TSymbolTable
 {
   public:
     TSymbolTable()
+        : mGlobalInvariant(false)
     {
         // The symbol table cannot be used until push() is called, but
         // the lack of an initial call to push() can be used to detect
         // that the symbol table has not been preloaded with built-ins.
     }
 
     ~TSymbolTable();
 
@@ -403,27 +406,49 @@ class TSymbolTable
         (*precisionStack[indexOfLastElement])[type.type] = prec;
         return true;
     }
 
     // Searches down the precisionStack for a precision qualifier
     // for the specified TBasicType
     TPrecision getDefaultPrecision(TBasicType type) const;
 
+    // This records invariant varyings declared through
+    // "invariant varying_name;".
+    void addInvariantVarying(const std::string &originalName)
+    {
+        mInvariantVaryings.insert(originalName);
+    }
+    // If this returns false, the varying could still be invariant
+    // if it is set as invariant during the varying variable
+    // declaration - this piece of information is stored in the
+    // variable's type, not here.
+    bool isVaryingInvariant(const std::string &originalName) const
+    {
+      return (mGlobalInvariant ||
+              mInvariantVaryings.count(originalName) > 0);
+    }
+
+    void setGlobalInvariant() { mGlobalInvariant = true; }
+    bool getGlobalInvariant() const { return mGlobalInvariant; }
+
     static int nextUniqueId()
     {
         return ++uniqueIdCounter;
     }
 
   private:
     ESymbolLevel currentLevel() const
     {
         return static_cast<ESymbolLevel>(table.size() - 1);
     }
 
     std::vector<TSymbolTableLevel *> table;
     typedef TMap<TBasicType, TPrecision> PrecisionStackLevel;
     std::vector< PrecisionStackLevel *> precisionStack;
 
+    std::set<std::string> mInvariantVaryings;
+    bool mGlobalInvariant;
+
     static int uniqueIdCounter;
 };
 
 #endif // _SYMBOL_TABLE_INCLUDED_
--- a/gfx/angle/src/compiler/translator/TranslatorESSL.cpp
+++ b/gfx/angle/src/compiler/translator/TranslatorESSL.cpp
@@ -11,16 +11,18 @@
 
 TranslatorESSL::TranslatorESSL(sh::GLenum type, ShShaderSpec spec)
     : TCompiler(type, spec, SH_ESSL_OUTPUT) {
 }
 
 void TranslatorESSL::translate(TIntermNode* root) {
     TInfoSinkBase& sink = getInfoSink().obj;
 
+    writePragma();
+
     // Write built-in extension behaviors.
     writeExtensionBehavior();
 
     // Write emulated built-in functions if needed.
     getBuiltInFunctionEmulator().OutputEmulatedFunctionDefinition(
         sink, getShaderType() == GL_FRAGMENT_SHADER);
 
     // Write array bounds clamping emulation if needed.
--- a/gfx/angle/src/compiler/translator/TranslatorGLSL.cpp
+++ b/gfx/angle/src/compiler/translator/TranslatorGLSL.cpp
@@ -4,53 +4,57 @@
 // found in the LICENSE file.
 //
 
 #include "compiler/translator/TranslatorGLSL.h"
 
 #include "compiler/translator/OutputGLSL.h"
 #include "compiler/translator/VersionGLSL.h"
 
-static void writeVersion(sh::GLenum type, TIntermNode* root,
-                         TInfoSinkBase& sink) {
-    TVersionGLSL versionGLSL(type);
-    root->traverse(&versionGLSL);
-    int version = versionGLSL.getVersion();
-    // We need to write version directive only if it is greater than 110.
-    // If there is no version directive in the shader, 110 is implied.
-    if (version > 110) {
-        sink << "#version " << version << "\n";
-    }
-}
-
 TranslatorGLSL::TranslatorGLSL(sh::GLenum type, ShShaderSpec spec)
     : TCompiler(type, spec, SH_GLSL_OUTPUT) {
 }
 
 void TranslatorGLSL::translate(TIntermNode* root) {
     TInfoSinkBase& sink = getInfoSink().obj;
 
     // Write GLSL version.
-    writeVersion(getShaderType(), root, sink);
+    writeVersion(root);
+
+    writePragma();
 
     // Write extension behaviour as needed
     writeExtensionBehavior();
 
     // Write emulated built-in functions if needed.
     getBuiltInFunctionEmulator().OutputEmulatedFunctionDefinition(
         sink, false);
 
     // Write array bounds clamping emulation if needed.
     getArrayBoundsClamper().OutputClampingFunctionDefinition(sink);
 
     // Write translated shader.
     TOutputGLSL outputGLSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(), getSymbolTable(), getShaderVersion());
     root->traverse(&outputGLSL);
 }
 
+void TranslatorGLSL::writeVersion(TIntermNode *root)
+{
+    TVersionGLSL versionGLSL(getShaderType(), getPragma());
+    root->traverse(&versionGLSL);
+    int version = versionGLSL.getVersion();
+    // We need to write version directive only if it is greater than 110.
+    // If there is no version directive in the shader, 110 is implied.
+    if (version > 110)
+    {
+        TInfoSinkBase& sink = getInfoSink().obj;
+        sink << "#version " << version << "\n";
+    }
+}
+
 void TranslatorGLSL::writeExtensionBehavior() {
     TInfoSinkBase& sink = getInfoSink().obj;
     const TExtensionBehavior& extensionBehavior = getExtensionBehavior();
     for (TExtensionBehavior::const_iterator iter = extensionBehavior.begin();
          iter != extensionBehavior.end(); ++iter) {
         if (iter->second == EBhUndefined)
             continue;
 
--- a/gfx/angle/src/compiler/translator/TranslatorGLSL.h
+++ b/gfx/angle/src/compiler/translator/TranslatorGLSL.h
@@ -4,20 +4,22 @@
 // found in the LICENSE file.
 //
 
 #ifndef COMPILER_TRANSLATORGLSL_H_
 #define COMPILER_TRANSLATORGLSL_H_
 
 #include "compiler/translator/Compiler.h"
 
-class TranslatorGLSL : public TCompiler {
-public:
+class TranslatorGLSL : public TCompiler
+{
+  public:
     TranslatorGLSL(sh::GLenum type, ShShaderSpec spec);
 
-protected:
-    virtual void translate(TIntermNode* root);
+  protected:
+    virtual void translate(TIntermNode *root);
 
-private:
+  private:
+    void writeVersion(TIntermNode *root);
     void writeExtensionBehavior();
 };
 
 #endif  // COMPILER_TRANSLATORGLSL_H_
--- a/gfx/angle/src/compiler/translator/ValidateLimitations.cpp
+++ b/gfx/angle/src/compiler/translator/ValidateLimitations.cpp
@@ -89,16 +89,17 @@ const char *GetOperatorString(TOperator 
       case EOpMatrixTimesVector:
       case EOpMatrixTimesScalar:
       case EOpMatrixTimesMatrix: return "*";
 
       case EOpLogicalOr: return "||";
       case EOpLogicalXor: return "^^";
       case EOpLogicalAnd: return "&&";
       case EOpNegative: return "-";
+      case EOpPositive: return "+";
       case EOpVectorLogicalNot: return "not";
       case EOpLogicalNot: return "!";
       case EOpPostIncrement: return "++";
       case EOpPostDecrement: return "--";
       case EOpPreIncrement: return "++";
       case EOpPreDecrement: return "--";
 
       case EOpRadians: return "radians";
--- a/gfx/angle/src/compiler/translator/VariableInfo.cpp
+++ b/gfx/angle/src/compiler/translator/VariableInfo.cpp
@@ -1,15 +1,16 @@
 //
 // Copyright (c) 2002-2013 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 "angle_gl.h"
+#include "compiler/translator/SymbolTable.h"
 #include "compiler/translator/VariableInfo.h"
 #include "compiler/translator/util.h"
 #include "common/utilities.h"
 
 namespace sh
 {
 
 namespace
@@ -126,26 +127,30 @@ VarT *FindVariable(const TString &name,
 
 }
 
 CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs,
                                    std::vector<sh::Attribute> *outputVariables,
                                    std::vector<sh::Uniform> *uniforms,
                                    std::vector<sh::Varying> *varyings,
                                    std::vector<sh::InterfaceBlock> *interfaceBlocks,
-                                   ShHashFunction64 hashFunction)
+                                   ShHashFunction64 hashFunction,
+                                   const TSymbolTable &symbolTable)
     : mAttribs(attribs),
       mOutputVariables(outputVariables),
       mUniforms(uniforms),
       mVaryings(varyings),
       mInterfaceBlocks(interfaceBlocks),
       mPointCoordAdded(false),
       mFrontFacingAdded(false),
       mFragCoordAdded(false),
-      mHashFunction(hashFunction)
+      mPositionAdded(false),
+      mPointSizeAdded(false),
+      mHashFunction(hashFunction),
+      mSymbolTable(symbolTable)
 {
 }
 
 // We want to check whether a uniform/varying is statically used
 // because we only count the used ones in packing computing.
 // Also, gl_FragCoord, gl_PointCoord, and gl_FrontFacing count
 // toward varying counting if they are statically used in a fragment
 // shader.
@@ -195,69 +200,109 @@ void CollectVariables::visitSymbol(TInte
                 // It's an internal error to reference an undefined user uniform
                 ASSERT(symbolName.compare(0, 3, "gl_") == 0 || var);
             }
             break;
           case EvqFragCoord:
             if (!mFragCoordAdded)
             {
                 Varying info;
-                info.name = "gl_FragCoord";
-                info.mappedName = "gl_FragCoord";
+                const char kName[] = "gl_FragCoord";
+                info.name = kName;
+                info.mappedName = kName;
                 info.type = GL_FLOAT_VEC4;
                 info.arraySize = 0;
-                info.precision = GL_MEDIUM_FLOAT;  // Use mediump as it doesn't really matter.
+                info.precision = GL_MEDIUM_FLOAT;  // Defined by spec.
                 info.staticUse = true;
+                info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
                 mVaryings->push_back(info);
                 mFragCoordAdded = true;
             }
             return;
           case EvqFrontFacing:
             if (!mFrontFacingAdded)
             {
                 Varying info;
-                info.name = "gl_FrontFacing";
-                info.mappedName = "gl_FrontFacing";
+                const char kName[] = "gl_FrontFacing";
+                info.name = kName;
+                info.mappedName = kName;
                 info.type = GL_BOOL;
                 info.arraySize = 0;
                 info.precision = GL_NONE;
                 info.staticUse = true;
+                info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
                 mVaryings->push_back(info);
                 mFrontFacingAdded = true;
             }
             return;
           case EvqPointCoord:
             if (!mPointCoordAdded)
             {
                 Varying info;
-                info.name = "gl_PointCoord";
-                info.mappedName = "gl_PointCoord";
+                const char kName[] = "gl_PointCoord";
+                info.name = kName;
+                info.mappedName = kName;
                 info.type = GL_FLOAT_VEC2;
                 info.arraySize = 0;
-                info.precision = GL_MEDIUM_FLOAT;  // Use mediump as it doesn't really matter.
+                info.precision = GL_MEDIUM_FLOAT;  // Defined by spec.
                 info.staticUse = true;
+                info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
                 mVaryings->push_back(info);
                 mPointCoordAdded = true;
             }
             return;
+          case EvqPosition:
+            if (!mPositionAdded)
+            {
+                Varying info;
+                const char kName[] = "gl_Position";
+                info.name = kName;
+                info.mappedName = kName;
+                info.type = GL_FLOAT_VEC4;
+                info.arraySize = 0;
+                info.precision = GL_HIGH_FLOAT;  // Defined by spec.
+                info.staticUse = true;
+                info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
+                mVaryings->push_back(info);
+                mPositionAdded = true;
+            }
+            return;
+          case EvqPointSize:
+            if (!mPointSizeAdded)
+            {
+                Varying info;
+                const char kName[] = "gl_PointSize";
+                info.name = kName;
+                info.mappedName = kName;
+                info.type = GL_FLOAT;
+                info.arraySize = 0;
+                info.precision = GL_MEDIUM_FLOAT;  // Defined by spec.
+                info.staticUse = true;
+                info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
+                mVaryings->push_back(info);
+                mPointSizeAdded = true;
+            }
+            return;
           default:
             break;
         }
     }
     if (var)
     {
         var->staticUse = true;
     }
 }
 
 class NameHashingTraverser : public GetVariableTraverser
 {
   public:
-    NameHashingTraverser(ShHashFunction64 hashFunction)
-        : mHashFunction(hashFunction)
+    NameHashingTraverser(ShHashFunction64 hashFunction,
+                         const TSymbolTable &symbolTable)
+        : GetVariableTraverser(symbolTable),
+          mHashFunction(hashFunction)
     {}
 
   private:
     DISALLOW_COPY_AND_ASSIGN(NameHashingTraverser);
 
     virtual void visitVariable(ShaderVariable *variable)
     {
         TString stringName = TString(variable->name.c_str());
@@ -307,30 +352,30 @@ void CollectVariables::visitVariable(con
     const TFieldList &fieldList = blockType->fields();
 
     for (size_t fieldIndex = 0; fieldIndex < fieldList.size(); ++fieldIndex)
     {
         const TField &field = *fieldList[fieldIndex];
         const TString &fullFieldName = InterfaceBlockFieldName(*blockType, field);
         const TType &fieldType = *field.type();
 
-        GetVariableTraverser traverser;
+        GetVariableTraverser traverser(mSymbolTable);
         traverser.traverse(fieldType, fullFieldName, &interfaceBlock.fields);
 
         interfaceBlock.fields.back().isRowMajorLayout = (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
     }
 
     infoList->push_back(interfaceBlock);
 }
 
 template <typename VarT>
 void CollectVariables::visitVariable(const TIntermSymbol *variable,
                                      std::vector<VarT> *infoList) const
 {
-    NameHashingTraverser traverser(mHashFunction);
+    NameHashingTraverser traverser(mHashFunction, mSymbolTable);
     traverser.traverse(variable->getType(), variable->getSymbol(), infoList);
 }
 
 template <typename VarT>
 void CollectVariables::visitInfoList(const TIntermSequence &sequence,
                                      std::vector<VarT> *infoList) const
 {
     for (size_t seqIndex = 0; seqIndex < sequence.size(); seqIndex++)
@@ -416,23 +461,19 @@ bool CollectVariables::visitBinary(Visit
         ASSERT(fieldIndex < namedBlock->fields.size());
         namedBlock->fields[fieldIndex].staticUse = true;
         return false;
     }
 
     return true;
 }
 
-template <typename VarT>
-void ExpandVariables(const std::vector<VarT> &compact,
-                     std::vector<ShaderVariable> *expanded)
+void ExpandUniforms(const std::vector<Uniform> &compact,
+                    std::vector<ShaderVariable> *expanded)
 {
     for (size_t variableIndex = 0; variableIndex < compact.size(); variableIndex++)
     {
         const ShaderVariable &variable = compact[variableIndex];
         ExpandVariable(variable, variable.name, variable.mappedName, variable.staticUse, expanded);
     }
 }
 
-template void ExpandVariables(const std::vector<Uniform> &, std::vector<ShaderVariable> *);
-template void ExpandVariables(const std::vector<Varying> &, std::vector<ShaderVariable> *);
-
 }
--- a/gfx/angle/src/compiler/translator/VariableInfo.h
+++ b/gfx/angle/src/compiler/translator/VariableInfo.h
@@ -6,29 +6,32 @@
 
 #ifndef COMPILER_VARIABLE_INFO_H_
 #define COMPILER_VARIABLE_INFO_H_
 
 #include <GLSLANG/ShaderLang.h>
 
 #include "compiler/translator/IntermNode.h"
 
+class TSymbolTable;
+
 namespace sh
 {
 
 // Traverses intermediate tree to collect all attributes, uniforms, varyings.
 class CollectVariables : public TIntermTraverser
 {
   public:
     CollectVariables(std::vector<Attribute> *attribs,
                      std::vector<Attribute> *outputVariables,
                      std::vector<Uniform> *uniforms,
                      std::vector<Varying> *varyings,
                      std::vector<InterfaceBlock> *interfaceBlocks,
-                     ShHashFunction64 hashFunction);
+                     ShHashFunction64 hashFunction,
+                     const TSymbolTable &symbolTable);
 
     virtual void visitSymbol(TIntermSymbol *symbol);
     virtual bool visitAggregate(Visit, TIntermAggregate *node);
     virtual bool visitBinary(Visit visit, TIntermBinary *binaryNode);
 
   private:
     template <typename VarT>
     void visitVariable(const TIntermSymbol *variable, std::vector<VarT> *infoList) const;
@@ -43,19 +46,23 @@ class CollectVariables : public TIntermT
     std::vector<InterfaceBlock> *mInterfaceBlocks;
 
     std::map<std::string, InterfaceBlockField *> mInterfaceBlockFields;
 
     bool mPointCoordAdded;
     bool mFrontFacingAdded;
     bool mFragCoordAdded;
 
+    bool mPositionAdded;
+    bool mPointSizeAdded;
+
     ShHashFunction64 mHashFunction;
+
+    const TSymbolTable &mSymbolTable;
 };
 
-// Expand struct variables to flattened lists of split variables
-template <typename VarT>
-void ExpandVariables(const std::vector<VarT> &compact,
-                     std::vector<ShaderVariable> *expanded);
+// Expand struct uniforms to flattened lists of split variables
+void ExpandUniforms(const std::vector<Uniform> &compact,
+                    std::vector<ShaderVariable> *expanded);
 
 }
 
 #endif  // COMPILER_VARIABLE_INFO_H_
--- a/gfx/angle/src/compiler/translator/VersionGLSL.cpp
+++ b/gfx/angle/src/compiler/translator/VersionGLSL.cpp
@@ -21,28 +21,22 @@ static const int GLSL_VERSION_120 = 120;
 //    not evaluate to l-values cannot be passed to parameters declared as
 //    out or inout."
 //    GLSL 1.1 section 5.8: "Other binary or unary expressions,
 //    non-dereferenced arrays, function names, swizzles with repeated fields,
 //    and constants cannot be l-values."
 //    GLSL 1.2 relaxed the restriction on arrays, section 5.8: "Variables that
 //    are built-in types, entire structures or arrays... are all l-values."
 //
-// TODO(alokp): The following two cases of invariant decalaration get lost
-// during parsing - they do not get carried over to the intermediate tree.
-// Handle these cases:
-// 1. When a pragma is used to force all output variables to be invariant:
-//    - #pragma STDGL invariant(all)
-// 2. When a previously decalared or built-in variable is marked invariant:
-//    - invariant gl_Position;
-//    - varying vec3 color; invariant color;
-//
-TVersionGLSL::TVersionGLSL(sh::GLenum type)
-    : mVersion(GLSL_VERSION_110)
+TVersionGLSL::TVersionGLSL(sh::GLenum type, const TPragma &pragma)
 {
+    if (pragma.stdgl.invariantAll)
+        mVersion = GLSL_VERSION_120;
+    else
+        mVersion = GLSL_VERSION_110;
 }
 
 void TVersionGLSL::visitSymbol(TIntermSymbol *node)
 {
     if (node->getSymbol() == "gl_PointCoord")
         updateVersion(GLSL_VERSION_120);
 }
 
--- a/gfx/angle/src/compiler/translator/VersionGLSL.h
+++ b/gfx/angle/src/compiler/translator/VersionGLSL.h
@@ -4,16 +4,18 @@
 // found in the LICENSE file.
 //
 
 #ifndef COMPILER_TRANSLATOR_VERSIONGLSL_H_
 #define COMPILER_TRANSLATOR_VERSIONGLSL_H_
 
 #include "compiler/translator/IntermNode.h"
 
+#include "compiler/translator/Pragma.h"
+
 // Traverses the intermediate tree to return the minimum GLSL version
 // required to legally access all built-in features used in the shader.
 // GLSL 1.1 which is mandated by OpenGL 2.0 provides:
 //   - #version and #extension to declare version and extensions.
 //   - built-in functions refract, exp, and log.
 //   - updated step() to compare x < edge instead of x <= edge.
 // GLSL 1.2 which is mandated by OpenGL 2.1 provides:
 //   - many changes to reduce differences when compared to the ES specification.
@@ -22,17 +24,17 @@
 //   - built-in variable gl_PointCoord for fragment shaders.
 //   - matrix constructors taking matrix as argument.
 //   - array as "out" function parameters
 //
 // TODO: ES3 equivalent versions of GLSL
 class TVersionGLSL : public TIntermTraverser
 {
   public:
-    TVersionGLSL(sh::GLenum type);
+    TVersionGLSL(sh::GLenum type, const TPragma &pragma);
 
     // Returns 120 if the following is used the shader:
     // - "invariant",
     // - "gl_PointCoord",
     // - matrix/matrix constructors
     // - array "out" parameters
     // Else 110 is returned.
     int getVersion() { return mVersion; }
--- a/gfx/angle/src/compiler/translator/glslang.y
+++ b/gfx/angle/src/compiler/translator/glslang.y
@@ -349,51 +349,68 @@ function_call
                     //
                     // A function call mapped to a built-in operation.
                     //
                     if (fnCandidate->getParamCount() == 1) {
                         //
                         // Treat it like a built-in unary operator.
                         //
                         $$ = context->intermediate.addUnaryMath(op, $1.intermNode, @1);
+                        const TType& returnType = fnCandidate->getReturnType();
+                        if (returnType.getBasicType() == EbtBool) {
+                            // Bool types should not have precision, so we'll override any precision
+                            // that might have been set by addUnaryMath.
+                            $$->setType(returnType);
+                        } else {
+                            // addUnaryMath has set the precision of the node based on the operand.
+                            $$->setTypePreservePrecision(returnType);
+                        }
                         if ($$ == 0)  {
                             std::stringstream extraInfoStream;
                             extraInfoStream << "built in unary operator function.  Type: " << static_cast<TIntermTyped*>($1.intermNode)->getCompleteString();
                             std::string extraInfo = extraInfoStream.str();
                             context->error($1.intermNode->getLine(), " wrong operand type", "Internal Error", extraInfo.c_str());
                             YYERROR;
                         }
                     } else {
-                        $$ = context->intermediate.setAggregateOperator($1.intermAggregate, op, @1);
+                        TIntermAggregate *aggregate = context->intermediate.setAggregateOperator($1.intermAggregate, op, @1);
+                        aggregate->setType(fnCandidate->getReturnType());
+                        aggregate->setPrecisionFromChildren();
+                        $$ = aggregate;
                     }
                 } else {
                     // This is a real function call
 
-                    $$ = context->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, @1);
-                    $$->setType(fnCandidate->getReturnType());
+                    TIntermAggregate *aggregate = context->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, @1);
+                    aggregate->setType(fnCandidate->getReturnType());
 
                     // this is how we know whether the given function is a builtIn function or a user defined function
                     // if builtIn == false, it's a userDefined -> could be an overloaded builtIn function also
                     // if builtIn == true, it's definitely a builtIn function with EOpNull
                     if (!builtIn)
-                        $$->getAsAggregate()->setUserDefined();
-                    $$->getAsAggregate()->setName(fnCandidate->getMangledName());
+                        aggregate->setUserDefined();
+                    aggregate->setName(fnCandidate->getMangledName());
+
+                    // This needs to happen after the name is set
+                    if (builtIn)
+                        aggregate->setBuiltInFunctionPrecision();
+
+                    $$ = aggregate;
 
                     TQualifier qual;
                     for (size_t i = 0; i < fnCandidate->getParamCount(); ++i) {
                         qual = fnCandidate->getParam(i).type->getQualifier();
                         if (qual == EvqOut || qual == EvqInOut) {
                             if (context->lValueErrorCheck($$->getLine(), "assign", (*($$->getAsAggregate()->getSequence()))[i]->getAsTyped())) {
                                 context->error($1.intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error");
                                 context->recover();
                             }
                         }
                     }
                 }
-                $$->setType(fnCandidate->getReturnType());
             } else {
                 // error message was put out by PaFindFunction()
                 // Put on a dummy node for error recovery
                 ConstantUnion *unionArray = new ConstantUnion[1];
                 unionArray->setFConst(0.0f);
                 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), @1);
                 context->recover();
             }
@@ -495,31 +512,32 @@ unary_expression
     }
     | unary_operator unary_expression {
         if ($1.op != EOpNull) {
             $$ = context->intermediate.addUnaryMath($1.op, $2, @1);
             if ($$ == 0) {
                 const char* errorOp = "";
                 switch($1.op) {
                 case EOpNegative:   errorOp = "-"; break;
+                case EOpPositive:   errorOp = "+"; break;
                 case EOpLogicalNot: errorOp = "!"; break;
                 default: break;
                 }
                 context->unaryOpError(@1, errorOp, $2->getCompleteString());
                 context->recover();
                 $$ = $2;
             }
         } else
             $$ = $2;
     }
     ;
 // Grammar Note:  No traditional style type casts.
 
 unary_operator
-    : PLUS  { $$.op = EOpNull; }
+    : PLUS  { $$.op = EOpPositive; }
     | DASH  { $$.op = EOpNegative; }
     | BANG  { $$.op = EOpLogicalNot; }
     ;
 // Grammar Note:  No '*' or '&' unary ops.  Pointers are not supported.
 
 multiplicative_expression
     : unary_expression { $$ = $1; }
     | multiplicative_expression STAR unary_expression {
--- a/gfx/angle/src/compiler/translator/glslang_tab.cpp
+++ b/gfx/angle/src/compiler/translator/glslang_tab.cpp
@@ -1,9 +1,9 @@
-/* A Bison parser, made by GNU Bison 2.7.1.  */
+/* A Bison parser, made by GNU Bison 2.7.12-4996.  */
 
 /* Bison implementation for Yacc-like parsers in C
    
       Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
@@ -39,17 +39,17 @@
    There are some unavoidable exceptions within include files to
    define necessary library symbols; they are noted "INFRINGES ON
    USER NAME SPACE" below.  */
 
 /* Identify Bison output.  */
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "2.7.1"
+#define YYBISON_VERSION "2.7.12-4996"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
 
 /* Pure parsers.  */
 #define YYPURE 1
 
 /* Push parsers.  */
@@ -791,41 +791,41 @@ static const yytype_int16 yyrhs[] =
      215,   216,    -1,   217,    -1,   160,    -1,    -1,   161,   218,
      201,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
        0,   206,   206,   207,   210,   234,   237,   242,   247,   252,
-     257,   263,   266,   269,   272,   275,   285,   298,   306,   406,
-     409,   417,   420,   426,   430,   437,   443,   452,   460,   463,
-     473,   476,   486,   496,   517,   518,   519,   524,   525,   533,
-     544,   545,   553,   564,   568,   569,   579,   589,   599,   612,
-     613,   623,   636,   640,   644,   648,   649,   662,   663,   676,
-     677,   690,   691,   708,   709,   722,   723,   724,   725,   726,
-     730,   733,   744,   752,   760,   787,   793,   804,   808,   812,
-     816,   823,   879,   882,   889,   897,   918,   939,   949,   977,
-     982,   992,   997,  1007,  1010,  1013,  1016,  1022,  1029,  1032,
-    1036,  1040,  1044,  1051,  1055,  1059,  1066,  1070,  1074,  1081,
-    1090,  1096,  1099,  1105,  1111,  1118,  1127,  1136,  1144,  1147,
-    1154,  1158,  1165,  1168,  1172,  1176,  1185,  1194,  1202,  1212,
-    1224,  1227,  1230,  1236,  1243,  1246,  1252,  1255,  1258,  1264,
-    1267,  1282,  1286,  1290,  1294,  1298,  1302,  1307,  1312,  1317,
-    1322,  1327,  1332,  1337,  1342,  1347,  1352,  1357,  1362,  1367,
-    1372,  1377,  1382,  1387,  1392,  1397,  1402,  1407,  1411,  1415,
-    1419,  1423,  1427,  1431,  1435,  1439,  1443,  1447,  1451,  1455,
-    1459,  1463,  1467,  1475,  1483,  1487,  1500,  1500,  1503,  1503,
-    1509,  1512,  1528,  1531,  1540,  1544,  1550,  1557,  1572,  1576,
-    1580,  1581,  1587,  1588,  1589,  1590,  1591,  1595,  1596,  1596,
-    1596,  1606,  1607,  1611,  1611,  1612,  1612,  1617,  1620,  1630,
-    1633,  1639,  1640,  1644,  1652,  1656,  1666,  1671,  1688,  1688,
-    1693,  1693,  1700,  1700,  1708,  1711,  1717,  1720,  1726,  1730,
-    1737,  1744,  1751,  1758,  1769,  1778,  1782,  1789,  1792,  1798,
-    1798
+     257,   263,   266,   269,   272,   275,   285,   298,   306,   423,
+     426,   434,   437,   443,   447,   454,   460,   469,   477,   480,
+     490,   493,   503,   513,   535,   536,   537,   542,   543,   551,
+     562,   563,   571,   582,   586,   587,   597,   607,   617,   630,
+     631,   641,   654,   658,   662,   666,   667,   680,   681,   694,
+     695,   708,   709,   726,   727,   740,   741,   742,   743,   744,
+     748,   751,   762,   770,   778,   805,   811,   822,   826,   830,
+     834,   841,   897,   900,   907,   915,   936,   957,   967,   995,
+    1000,  1010,  1015,  1025,  1028,  1031,  1034,  1040,  1047,  1050,
+    1054,  1058,  1062,  1069,  1073,  1077,  1084,  1088,  1092,  1099,
+    1108,  1114,  1117,  1123,  1129,  1136,  1145,  1154,  1162,  1165,
+    1172,  1176,  1183,  1186,  1190,  1194,  1203,  1212,  1220,  1230,
+    1242,  1245,  1248,  1254,  1261,  1264,  1270,  1273,  1276,  1282,
+    1285,  1300,  1304,  1308,  1312,  1316,  1320,  1325,  1330,  1335,
+    1340,  1345,  1350,  1355,  1360,  1365,  1370,  1375,  1380,  1385,
+    1390,  1395,  1400,  1405,  1410,  1415,  1420,  1425,  1429,  1433,
+    1437,  1441,  1445,  1449,  1453,  1457,  1461,  1465,  1469,  1473,
+    1477,  1481,  1485,  1493,  1501,  1505,  1518,  1518,  1521,  1521,
+    1527,  1530,  1546,  1549,  1558,  1562,  1568,  1575,  1590,  1594,
+    1598,  1599,  1605,  1606,  1607,  1608,  1609,  1613,  1614,  1614,
+    1614,  1624,  1625,  1629,  1629,  1630,  1630,  1635,  1638,  1648,
+    1651,  1657,  1658,  1662,  1670,  1674,  1684,  1689,  1706,  1706,
+    1711,  1711,  1718,  1718,  1726,  1729,  1735,  1738,  1744,  1748,
+    1755,  1762,  1769,  1776,  1787,  1796,  1800,  1807,  1810,  1816,
+    1816
 };
 #endif
 
 #if YYDEBUG || YYERROR_VERBOSE || 0
 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
    First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
 static const char *const yytname[] =
 {
@@ -2731,51 +2731,68 @@ yyreduce:
                     //
                     // A function call mapped to a built-in operation.
                     //
                     if (fnCandidate->getParamCount() == 1) {
                         //
                         // Treat it like a built-in unary operator.
                         //
                         (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(op, (yyvsp[(1) - (1)].interm).intermNode, (yylsp[(1) - (1)]));
+                        const TType& returnType = fnCandidate->getReturnType();
+                        if (returnType.getBasicType() == EbtBool) {
+                            // Bool types should not have precision, so we'll override any precision
+                            // that might have been set by addUnaryMath.
+                            (yyval.interm.intermTypedNode)->setType(returnType);
+                        } else {
+                            // addUnaryMath has set the precision of the node based on the operand.
+                            (yyval.interm.intermTypedNode)->setTypePreservePrecision(returnType);
+                        }
                         if ((yyval.interm.intermTypedNode) == 0)  {
                             std::stringstream extraInfoStream;
                             extraInfoStream << "built in unary operator function.  Type: " << static_cast<TIntermTyped*>((yyvsp[(1) - (1)].interm).intermNode)->getCompleteString();
                             std::string extraInfo = extraInfoStream.str();
                             context->error((yyvsp[(1) - (1)].interm).intermNode->getLine(), " wrong operand type", "Internal Error", extraInfo.c_str());
                             YYERROR;
                         }
                     } else {
-                        (yyval.interm.intermTypedNode) = context->intermediate.setAggregateOperator((yyvsp[(1) - (1)].interm).intermAggregate, op, (yylsp[(1) - (1)]));
+                        TIntermAggregate *aggregate = context->intermediate.setAggregateOperator((yyvsp[(1) - (1)].interm).intermAggregate, op, (yylsp[(1) - (1)]));
+                        aggregate->setType(fnCandidate->getReturnType());
+                        aggregate->setPrecisionFromChildren();
+                        (yyval.interm.intermTypedNode) = aggregate;
                     }
                 } else {
                     // This is a real function call
 
-                    (yyval.interm.intermTypedNode) = context->intermediate.setAggregateOperator((yyvsp[(1) - (1)].interm).intermAggregate, EOpFunctionCall, (yylsp[(1) - (1)]));
-                    (yyval.interm.intermTypedNode)->setType(fnCandidate->getReturnType());
+                    TIntermAggregate *aggregate = context->intermediate.setAggregateOperator((yyvsp[(1) - (1)].interm).intermAggregate, EOpFunctionCall, (yylsp[(1) - (1)]));
+                    aggregate->setType(fnCandidate->getReturnType());
 
                     // this is how we know whether the given function is a builtIn function or a user defined function
                     // if builtIn == false, it's a userDefined -> could be an overloaded builtIn function also
                     // if builtIn == true, it's definitely a builtIn function with EOpNull
                     if (!builtIn)
-                        (yyval.interm.intermTypedNode)->getAsAggregate()->setUserDefined();
-                    (yyval.interm.intermTypedNode)->getAsAggregate()->setName(fnCandidate->getMangledName());
+                        aggregate->setUserDefined();
+                    aggregate->setName(fnCandidate->getMangledName());
+
+                    // This needs to happen after the name is set
+                    if (builtIn)
+                        aggregate->setBuiltInFunctionPrecision();
+
+                    (yyval.interm.intermTypedNode) = aggregate;
 
                     TQualifier qual;
                     for (size_t i = 0; i < fnCandidate->getParamCount(); ++i) {
                         qual = fnCandidate->getParam(i).type->getQualifier();
                         if (qual == EvqOut || qual == EvqInOut) {
                             if (context->lValueErrorCheck((yyval.interm.intermTypedNode)->getLine(), "assign", (*((yyval.interm.intermTypedNode)->getAsAggregate()->getSequence()))[i]->getAsTyped())) {
                                 context->error((yyvsp[(1) - (1)].interm).intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error");
                                 context->recover();
                             }
                         }
                     }
                 }
-                (yyval.interm.intermTypedNode)->setType(fnCandidate->getReturnType());
             } else {
                 // error message was put out by PaFindFunction()
                 // Put on a dummy node for error recovery
                 ConstantUnion *unionArray = new ConstantUnion[1];
                 unionArray->setFConst(0.0f);
                 (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), (yylsp[(1) - (1)]));
                 context->recover();
             }
@@ -2914,31 +2931,32 @@ yyreduce:
 
     {
         if ((yyvsp[(1) - (2)].interm).op != EOpNull) {
             (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath((yyvsp[(1) - (2)].interm).op, (yyvsp[(2) - (2)].interm.intermTypedNode), (yylsp[(1) - (2)]));
             if ((yyval.interm.intermTypedNode) == 0) {
                 const char* errorOp = "";
                 switch((yyvsp[(1) - (2)].interm).op) {
                 case EOpNegative:   errorOp = "-"; break;
+                case EOpPositive:   errorOp = "+"; break;
                 case EOpLogicalNot: errorOp = "!"; break;
                 default: break;
                 }
                 context->unaryOpError((yylsp[(1) - (2)]), errorOp, (yyvsp[(2) - (2)].interm.intermTypedNode)->getCompleteString());
                 context->recover();
                 (yyval.interm.intermTypedNode) = (yyvsp[(2) - (2)].interm.intermTypedNode);
             }
         } else
             (yyval.interm.intermTypedNode) = (yyvsp[(2) - (2)].interm.intermTypedNode);
     }
     break;
 
   case 34:
 
-    { (yyval.interm).op = EOpNull; }
+    { (yyval.interm).op = EOpPositive; }
     break;
 
   case 35:
 
     { (yyval.interm).op = EOpNegative; }
     break;
 
   case 36:
--- a/gfx/angle/src/compiler/translator/glslang_tab.h
+++ b/gfx/angle/src/compiler/translator/glslang_tab.h
@@ -1,9 +1,9 @@
-/* A Bison parser, made by GNU Bison 2.7.1.  */
+/* A Bison parser, made by GNU Bison 2.7.12-4996.  */
 
 /* Bison interface for Yacc-like parsers in C
    
       Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
--- a/gfx/angle/src/compiler/translator/intermOut.cpp
+++ b/gfx/angle/src/compiler/translator/intermOut.cpp
@@ -57,17 +57,19 @@ void OutputTreeText(TInfoSinkBase &sink,
 }  // namespace anonymous
 
 
 TString TType::getCompleteString() const
 {
     TStringStream stream;
 
     if (qualifier != EvqTemporary && qualifier != EvqGlobal)
-        stream << getQualifierString() << " " << getPrecisionString() << " ";
+        stream << getQualifierString() << " ";
+    if (precision != EbpUndefined)
+        stream << getPrecisionString() << " ";
     if (array)
         stream << "array[" << getArraySize() << "] of ";
     if (isMatrix())
         stream << getCols() << "X" << getRows() << " matrix of ";
     else if (isVector())
         stream << getNominalSize() << "-component vector of ";
 
     stream << getBasicString();
@@ -216,16 +218,17 @@ bool TOutputTraverser::visitUnary(Visit 
 {
     TInfoSinkBase& out = sink;
 
     OutputTreeText(out, node, mDepth);
 
     switch (node->getOp())
     {
       case EOpNegative:       out << "Negate value";         break;
+      case EOpPositive:       out << "Positive sign";        break;
       case EOpVectorLogicalNot:
       case EOpLogicalNot:     out << "Negate conditional";   break;
 
       case EOpPostIncrement:  out << "Post-Increment";       break;
       case EOpPostDecrement:  out << "Post-Decrement";       break;
       case EOpPreIncrement:   out << "Pre-Increment";        break;
       case EOpPreDecrement:   out << "Pre-Decrement";        break;
 
--- a/gfx/angle/src/compiler/translator/util.cpp
+++ b/gfx/angle/src/compiler/translator/util.cpp
@@ -4,16 +4,17 @@
 // found in the LICENSE file.
 //
 
 #include "compiler/translator/util.h"
 
 #include <limits>
 
 #include "compiler/preprocessor/numeric_lex.h"
+#include "compiler/translator/SymbolTable.h"
 #include "common/utilities.h"
 
 bool atof_clamp(const char *str, float *value)
 {
     bool success = pp::numeric_lex_float(str, value);
     if (!success)
         *value = std::numeric_limits<float>::max();
     return success;
@@ -276,18 +277,57 @@ InterpolationType GetInterpolationType(T
       case EvqCentroidOut:
         return INTERPOLATION_CENTROID;
 
       default: UNREACHABLE();
         return INTERPOLATION_SMOOTH;
     }
 }
 
+GetVariableTraverser::GetVariableTraverser(const TSymbolTable &symbolTable)
+    : mSymbolTable(symbolTable)
+{
+}
+
+template void GetVariableTraverser::setTypeSpecificInfo(
+    const TType &type, const TString& name, InterfaceBlockField *variable);
+template void GetVariableTraverser::setTypeSpecificInfo(
+    const TType &type, const TString& name, ShaderVariable *variable);
+template void GetVariableTraverser::setTypeSpecificInfo(
+    const TType &type, const TString& name, Uniform *variable);
+
+template<>
+void GetVariableTraverser::setTypeSpecificInfo(
+    const TType &type, const TString& name, Varying *variable)
+{
+    ASSERT(variable);
+    switch (type.getQualifier())
+    {
+      case EvqInvariantVaryingIn:
+      case EvqInvariantVaryingOut:
+        variable->isInvariant = true;
+        break;
+      case EvqVaryingIn:
+      case EvqVaryingOut:
+        if (mSymbolTable.isVaryingInvariant(std::string(name.c_str())))
+        {
+            variable->isInvariant = true;
+        }
+        break;
+      default:
+        break;
+    }
+
+    variable->interpolation = GetInterpolationType(type.getQualifier());
+}
+
 template <typename VarT>
-void GetVariableTraverser::traverse(const TType &type, const TString &name, std::vector<VarT> *output)
+void GetVariableTraverser::traverse(const TType &type,
+                                    const TString &name,
+                                    std::vector<VarT> *output)
 {
     const TStructure *structure = type.getStruct();
 
     VarT variable;
     variable.name = name.c_str();
     variable.arraySize = static_cast<unsigned int>(type.getArraySize());
 
     if (!structure)
@@ -304,20 +344,21 @@ void GetVariableTraverser::traverse(cons
         const TFieldList &fields = structure->fields();
 
         for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
         {
             TField *field = fields[fieldIndex];
             traverse(*field->type(), field->name(), &variable.fields);
         }
     }
-
+    setTypeSpecificInfo(type, name, &variable);
     visitVariable(&variable);
 
     ASSERT(output);
     output->push_back(variable);
 }
 
+template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<InterfaceBlockField> *);
+template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<ShaderVariable> *);
 template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Uniform> *);
 template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Varying> *);
-template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<InterfaceBlockField> *);
 
 }
--- a/gfx/angle/src/compiler/translator/util.h
+++ b/gfx/angle/src/compiler/translator/util.h
@@ -19,38 +19,48 @@
 //   2. it clamps the value to -FLT_MAX or FLT_MAX if overflow happens.
 // Return false if overflow happens.
 extern bool atof_clamp(const char *str, float *value);
 
 // If overflow happens, clamp the value to INT_MIN or INT_MAX.
 // Return false if overflow happens.
 extern bool atoi_clamp(const char *str, int *value);
 
+class TSymbolTable;
+
 namespace sh
 {
 
 GLenum GLVariableType(const TType &type);
 GLenum GLVariablePrecision(const TType &type);
 bool IsVaryingIn(TQualifier qualifier);
 bool IsVaryingOut(TQualifier qualifier);
 bool IsVarying(TQualifier qualifier);
 InterpolationType GetInterpolationType(TQualifier qualifier);
 TString ArrayString(const TType &type);
 
 class GetVariableTraverser
 {
   public:
-    GetVariableTraverser() {}
+    GetVariableTraverser(const TSymbolTable &symbolTable);
 
     template <typename VarT>
     void traverse(const TType &type, const TString &name, std::vector<VarT> *output);
 
   protected:
     // May be overloaded
     virtual void visitVariable(ShaderVariable *newVar) {}
 
   private:
+    // Helper function called by traverse() to fill specific fields
+    // for attributes/varyings/uniforms.
+    template <typename VarT>
+    void setTypeSpecificInfo(
+        const TType &type, const TString &name, VarT *variable) {}
+
+    const TSymbolTable &mSymbolTable;
+
     DISALLOW_COPY_AND_ASSIGN(GetVariableTraverser);
 };
 
 }
 
 #endif // COMPILER_UTIL_H
--- a/gfx/angle/src/libEGL.gypi
+++ b/gfx/angle/src/libEGL.gypi
@@ -1,17 +1,15 @@
 # Copyright (c) 2013 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.
 
 {
     'variables':
     {
-        'angle_enable_d3d9%': 1,
-        'angle_enable_d3d11%': 1,
         # This file list is shared with the GN build.
         'angle_libegl_sources':
         [
             '../include/EGL/egl.h',
             '../include/EGL/eglext.h',
             '../include/EGL/eglplatform.h',
             '../include/GLES2/gl2.h',
             '../include/GLES2/gl2ext.h',
@@ -35,30 +33,40 @@
             'common/mathutil.h',
             'common/platform.h',
             'common/NativeWindow.h',
             'common/tls.cpp',
             'common/tls.h',
             'common/utilities.cpp',
             'common/utilities.h',
             'common/version.h',
-            'common/win32/NativeWindow.cpp',
             'libEGL/Config.cpp',
             'libEGL/Config.h',
             'libEGL/Display.cpp',
             'libEGL/Display.h',
             'libEGL/Surface.cpp',
             'libEGL/Surface.h',
             'libEGL/libEGL.cpp',
             'libEGL/libEGL.def',
             'libEGL/libEGL.rc',
             'libEGL/main.cpp',
             'libEGL/main.h',
             'libEGL/resource.h',
         ],
+        'angle_libegl_win32_sources':
+        [
+            'common/win32/NativeWindow.cpp',
+        ],
+        'angle_libegl_winrt_sources':
+        [
+            'common/winrt/CoreWindowNativeWindow.cpp',
+            'common/winrt/CoreWindowNativeWindow.h',
+            'common/winrt/IInspectableNativeWindow.cpp',
+            'common/winrt/IInspectableNativeWindow.h',
+        ],
     },
     # Everything below this is duplicated in the GN build. If you change
     # anything also change angle/BUILD.gn
     'conditions':
     [
         ['OS=="win"',
         {
             'targets':
@@ -94,35 +102,81 @@
                         }],
                         ['angle_enable_d3d11==1',
                         {
                             'defines':
                             [
                                 'ANGLE_ENABLE_D3D11',
                             ],
                         }],
+                        ['angle_build_winrt==0',
+                        {
+                            'sources':
+                            [
+                                '<@(angle_libegl_win32_sources)',
+                            ],
+                        }],
+
+                        ['angle_build_winrt==1',
+                        {
+                            'defines':
+                            [
+                                'NTDDI_VERSION=NTDDI_WINBLUE',
+                            ],
+                            'sources':
+                            [
+                                '<@(angle_libegl_winrt_sources)',
+                            ],
+                            'msvs_enable_winrt' : '1',
+                            'msvs_requires_importlibrary' : '1',
+                            'msvs_settings':
+                            {
+                                'VCLinkerTool':
+                                {
+                                    'EnableCOMDATFolding': '1',
+                                    'OptimizeReferences': '1',
+                                }
+                            },
+                        }],
+                        ['angle_build_winphone==1',
+                        {
+                            'msvs_enable_winphone' : '1',
+                        }],
                     ],
                     'includes': [ '../build/common_defines.gypi', ],
                     'msvs_settings':
                     {
                         'VCLinkerTool':
                         {
-                            'AdditionalDependencies':
+                            'conditions':
                             [
-                                'd3d9.lib',
+                                ['angle_build_winrt==0',
+                                {
+                                    'AdditionalDependencies':
+                                    [
+                                        'd3d9.lib',
+                                    ],
+                                }],
+                                ['angle_build_winrt==1',
+                                {
+                                    'AdditionalDependencies':
+                                    [
+                                        'd3d11.lib',
+                                    ],
+                                }],
                             ],
                         },
                     },
                     'configurations':
                     {
-                        'Debug':
+                        'Debug_Base':
                         {
                             'defines':
                             [
-                                'ANGLE_ENABLE_PERF',
+                                'ANGLE_ENABLE_DEBUG_ANNOTATIONS',
                             ],
                         },
                     },
                 },
             ],
         },
         ],
     ],
--- a/gfx/angle/src/libEGL/Surface.cpp
+++ b/gfx/angle/src/libEGL/Surface.cpp
@@ -234,36 +234,38 @@ bool Surface::swapRect(EGLint x, EGLint 
     return true;
 }
 
 EGLNativeWindowType Surface::getWindowHandle()
 {
     return mNativeWindow.getNativeWindow();
 }
 
-
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
 #define kSurfaceProperty _TEXT("Egl::SurfaceOwner")
 #define kParentWndProc _TEXT("Egl::SurfaceParentWndProc")
 
 static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
 {
   if (message == WM_SIZE)
   {
       Surface* surf = reinterpret_cast<Surface*>(GetProp(hwnd, kSurfaceProperty));
       if(surf)
       {
           surf->checkForOutOfDateSwapChain();
       }
   }
   WNDPROC prevWndFunc = reinterpret_cast<WNDPROC >(GetProp(hwnd, kParentWndProc));
   return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam);
 }
+#endif
 
 void Surface::subclassWindow()
 {
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
     HWND window = mNativeWindow.getNativeWindow();
     if (!window)
     {
         return;
     }
 
     DWORD processId;
     DWORD threadId = GetWindowThreadProcessId(window, &processId);
@@ -278,25 +280,27 @@ void Surface::subclassWindow()
     {
         mWindowSubclassed = false;
         return;
     }
 
     SetProp(window, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
     SetProp(window, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
     mWindowSubclassed = true;
+#endif
 }
 
 void Surface::unsubclassWindow()
 {
     if(!mWindowSubclassed)
     {
         return;
     }
 
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
     HWND window = mNativeWindow.getNativeWindow();
     if (!window)
     {
         return;
     }
 
     // un-subclass
     LONG_PTR parentWndFunc = reinterpret_cast<LONG_PTR>(GetProp(window, kParentWndProc));
@@ -310,16 +314,17 @@ void Surface::unsubclassWindow()
     {
         LONG_PTR prevWndFunc = SetWindowLongPtr(window, GWLP_WNDPROC, parentWndFunc);
         UNUSED_ASSERTION_VARIABLE(prevWndFunc);
         ASSERT(prevWndFunc == reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
     }
 
     RemoveProp(window, kSurfaceProperty);
     RemoveProp(window, kParentWndProc);
+#endif
     mWindowSubclassed = false;
 }
 
 bool Surface::checkForOutOfDateSwapChain()
 {
     RECT client;
     int clientWidth = getWidth();
     int clientHeight = getHeight();
--- a/gfx/angle/src/libEGL/libEGL.cpp
+++ b/gfx/angle/src/libEGL/libEGL.cpp
@@ -115,21 +115,23 @@ EGLDisplay __stdcall eglGetPlatformDispl
         break;
 
       default:
         return egl::error(EGL_BAD_CONFIG, EGL_NO_DISPLAY);
     }
 
     EGLNativeDisplayType displayId = static_cast<EGLNativeDisplayType>(native_display);
 
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
     // Validate the display device context
     if (WindowFromDC(displayId) == NULL)
     {
         return egl::success(EGL_NO_DISPLAY);
     }
+#endif
 
     EGLint requestedDisplayType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
     if (attrib_list)
     {
         for (const EGLint *curAttrib = attrib_list; curAttrib[0] != EGL_NONE; curAttrib += 2)
         {
             switch (curAttrib[0])
             {
--- a/gfx/angle/src/libEGL/main.cpp
+++ b/gfx/angle/src/libEGL/main.cpp
@@ -50,17 +50,17 @@ void DeallocateCurrent()
 }
 
 extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
 {
     switch (reason)
     {
       case DLL_PROCESS_ATTACH:
         {
-#if defined(ANGLE_ENABLE_TRACE)
+#if defined(ANGLE_ENABLE_DEBUG_TRACE)
             FILE *debug = fopen(TRACE_OUTPUT_FILE, "rt");
 
             if (debug)
             {
                 fclose(debug);
                 debug = fopen(TRACE_OUTPUT_FILE, "wt");   // Erase
                 
                 if (debug)
@@ -70,32 +70,40 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE
             }
 #endif
 
             currentTLS = CreateTLSIndex();
             if (currentTLS == TLS_OUT_OF_INDEXES)
             {
                 return FALSE;
             }
+
+#ifdef ANGLE_ENABLE_DEBUG_ANNOTATIONS
+            gl::InitializeDebugAnnotations();
+#endif
         }
         // Fall through to initialize index
       case DLL_THREAD_ATTACH:
         {
             egl::AllocateCurrent();
         }
         break;
       case DLL_THREAD_DETACH:
         {
             egl::DeallocateCurrent();
         }
         break;
       case DLL_PROCESS_DETACH:
         {
             egl::DeallocateCurrent();
             DestroyTLSIndex(currentTLS);
+
+#ifdef ANGLE_ENABLE_DEBUG_ANNOTATIONS
+            gl::UninitializeDebugAnnotations();
+#endif
         }
         break;
       default:
         break;
     }
 
     return TRUE;
 }
--- a/gfx/angle/src/libGLESv2.gypi
+++ b/gfx/angle/src/libGLESv2.gypi
@@ -1,17 +1,15 @@
 # Copyright (c) 2013 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.
 
 {
     'variables':
     {
-        'angle_enable_d3d9%': 1,
-        'angle_enable_d3d11%': 1,
         # These file lists are shared with the GN build.
         'angle_libangle_sources':
         [
             '../include/EGL/egl.h',
             '../include/EGL/eglext.h',
             '../include/EGL/eglplatform.h',
             '../include/GLES2/gl2.h',
             '../include/GLES2/gl2ext.h',
@@ -28,26 +26,26 @@
             'common/angleutils.cpp',
             'common/angleutils.h',
             'common/blocklayout.cpp',
             'common/blocklayout.h',
             'common/debug.cpp',
             'common/debug.h',
             'common/event_tracer.cpp',
             'common/event_tracer.h',
+            'common/features.h',
             'common/mathutil.cpp',
             'common/mathutil.h',
             'common/platform.h',
             'common/NativeWindow.h',
             'common/tls.cpp',
             'common/tls.h',
             'common/utilities.cpp',
             'common/utilities.h',
             'common/version.h',
-            'common/win32/NativeWindow.cpp',
             'libGLESv2/BinaryStream.h',
             'libGLESv2/Buffer.cpp',
             'libGLESv2/Buffer.h',
             'libGLESv2/Caps.cpp',
             'libGLESv2/Caps.h',
             'libGLESv2/Constants.h',
             'libGLESv2/Context.cpp',
             'libGLESv2/Context.h',
@@ -99,16 +97,17 @@
             'libGLESv2/queryconversions.cpp',
             'libGLESv2/queryconversions.h',
             'libGLESv2/renderer/BufferImpl.h',
             'libGLESv2/renderer/FenceImpl.h',
             'libGLESv2/renderer/Image.cpp',
             'libGLESv2/renderer/Image.h',
             'libGLESv2/renderer/IndexRangeCache.cpp',
             'libGLESv2/renderer/IndexRangeCache.h',
+            'libGLESv2/renderer/ProgramImpl.cpp',
             'libGLESv2/renderer/ProgramImpl.h',
             'libGLESv2/renderer/QueryImpl.h',
             'libGLESv2/renderer/RenderTarget.h',
             'libGLESv2/renderer/Renderer.cpp',
             'libGLESv2/renderer/Renderer.h',
             'libGLESv2/renderer/ShaderExecutable.h',
             'libGLESv2/renderer/ShaderImpl.h',
             'libGLESv2/renderer/SwapChain.h',
@@ -136,16 +135,28 @@
             'libGLESv2/validationES2.h',
             'libGLESv2/validationES3.cpp',
             'libGLESv2/validationES3.h',
             'third_party/murmurhash/MurmurHash3.cpp',
             'third_party/murmurhash/MurmurHash3.h',
             'third_party/systeminfo/SystemInfo.cpp',
             'third_party/systeminfo/SystemInfo.h',
         ],
+        'angle_libangle_win_sources':
+        [
+            # TODO(kbr): port NativeWindow to other EGL platforms.
+            'common/win32/NativeWindow.cpp',
+        ],
+        'angle_libangle_winrt_sources':
+        [
+            'common/winrt/CoreWindowNativeWindow.cpp',
+            'common/winrt/CoreWindowNativeWindow.h',
+            'common/winrt/IInspectableNativeWindow.cpp',
+            'common/winrt/IInspectableNativeWindow.h',
+        ],
         'angle_d3d_shared_sources':
         [
             'libGLESv2/renderer/d3d/BufferD3D.cpp',
             'libGLESv2/renderer/d3d/BufferD3D.h',
             'libGLESv2/renderer/d3d/DynamicHLSL.cpp',
             'libGLESv2/renderer/d3d/DynamicHLSL.h',
             'libGLESv2/renderer/d3d/HLSLCompiler.cpp',
             'libGLESv2/renderer/d3d/HLSLCompiler.h',
@@ -301,163 +312,258 @@
             'libGLESv2/renderer/d3d/d3d11/TextureStorage11.h',
             'libGLESv2/renderer/d3d/d3d11/VertexArray11.h',
             'libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp',
             'libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h',
         ]
     },
     # Everything below this is duplicated in the GN build. If you change
     # anything also change angle/BUILD.gn
-    'conditions':
+    'targets':
     [
-        ['OS=="win"',
         {
-            'targets':
+            'target_name': 'libANGLE',
+            #TODO(jamdill/geofflang): support shared
+            'type': 'static_library',
+            'dependencies': [ 'translator', 'commit_id', ],
+            'includes': [ '../build/common_defines.gypi', ],
+
+            'include_dirs':
+            [
+                '.',
+                '../include',
+                'libGLESv2',
+            ],
+            'sources':
+            [
+                '<@(angle_libangle_sources)',
+            ],
+            'defines':
             [
+                'GL_APICALL=',
+                'GL_GLEXT_PROTOTYPES=',
+                'EGLAPI=',
+                'ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ "d3dcompiler_46.dll", "d3dcompiler_43.dll" }',
+            ],
+            'direct_dependent_settings':
+            {
+                'include_dirs':
+                [
+                    '.',
+                    '../include',
+                    'libGLESv2',
+                ],
+                'defines':
+                [
+                    'GL_APICALL=',
+                    'GL_GLEXT_PROTOTYPES=',
+                    'EGLAPI=',
+                    'ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ "d3dcompiler_46.dll", "d3dcompiler_43.dll" }',
+                ],
+            },
+            'conditions':
+            [
+                ['angle_enable_d3d9==1 or angle_enable_d3d11==1',
                 {
-                    'target_name': 'libANGLE',
-                    #TODO(jamdill/geofflang): support shared
-                    'type': 'static_library',
-                    'dependencies': [ 'translator', 'commit_id', 'copy_compiler_dll' ],
-                    'includes': [ '../build/common_defines.gypi', ],
-                    'include_dirs':
-                    [
-                        '.',
-                        '../include',
-                        'libGLESv2',
-                    ],
                     'sources':
                     [
-                        '<@(angle_libangle_sources)',
+                        '<@(angle_d3d_shared_sources)',
+                    ],
+                }],
+                ['angle_enable_d3d9==1',
+                {
+                    'sources':
+                    [
+                        '<@(angle_d3d9_sources)',
                     ],
                     'defines':
                     [
-                        'GL_APICALL=',
-                        'GL_GLEXT_PROTOTYPES=',
-                        'EGLAPI=',
-                        'ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ "d3dcompiler_46.dll", "d3dcompiler_43.dll" }',
+                        'ANGLE_ENABLE_D3D9',
                     ],
-                    'direct_dependent_settings':
+                    'link_settings':
                     {
-                        'include_dirs':
-                        [
-                            '.',
-                            '../include',
-                            'libGLESv2',
-                        ],
-                        'defines':
-                        [
-                            'GL_APICALL=',
-                            'GL_GLEXT_PROTOTYPES=',
-                            'EGLAPI=',
-                            'ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ "d3dcompiler_46.dll", "d3dcompiler_43.dll" }',
-                        ],
+                        'msvs_settings':
+                        {
+                            'VCLinkerTool':
+                            {
+                                'AdditionalDependencies':
+                                [
+                                    'd3d9.lib',
+                                ]
+                            }
+                        },
                     },
-                    'conditions':
+                }],
+                ['angle_enable_d3d11==1',
+                {
+                    'sources':
                     [
-                        ['angle_enable_d3d9==1 or angle_enable_d3d11==1',
-                        {
-                            'sources':
-                            [
-                                '<@(angle_d3d_shared_sources)',
-                            ],
-                        }],
-                        ['angle_enable_d3d9==1',
+                        '<@(angle_d3d11_sources)',
+                    ],
+                    'defines':
+                    [
+                        'ANGLE_ENABLE_D3D11',
+                    ],
+                    'link_settings':
+                    {
+                        'msvs_settings':
                         {
-                            'sources':
-                            [
-                                '<@(angle_d3d9_sources)',
-                            ],
-                            'defines':
-                            [
-                                'ANGLE_ENABLE_D3D9',
-                            ],
-                            'link_settings':
+                            'VCLinkerTool':
                             {
-                                'msvs_settings':
-                                {
-                                    'VCLinkerTool':
+                                'conditions':
+                                [
+                                    ['angle_build_winrt==0',
                                     {
                                         'AdditionalDependencies':
                                         [
-                                            'd3d9.lib',
-                                        ]
-                                    }
-                                },
-                            },
-                        }],
-                        ['angle_enable_d3d11==1',
-                        {
-                            'sources':
-                            [
-                                '<@(angle_d3d11_sources)',
-                            ],
-                            'defines':
-                            [
-                                'ANGLE_ENABLE_D3D11',
-                            ],
-                            'link_settings':
-                            {
-                                'msvs_settings':
-                                {
-                                    'VCLinkerTool':
+                                            'dxguid.lib',
+                                        ],
+                                    }],
+                                    ['angle_build_winrt==1',
                                     {
                                         'AdditionalDependencies':
                                         [
                                             'dxguid.lib',
-                                        ]
-                                    }
-                                },
-                            },
-                        }],
+                                            'd3d11.lib',
+                                            'd3dcompiler.lib',
+                                        ],
+                                    }],
+                                ],
+                            }
+                        },
+                    },
+                }],
+                ['angle_build_winrt==0 and OS=="win"',
+                {
+                    'sources':
+                    [
+                        '<@(angle_libangle_win_sources)',
+                    ],
+                    'dependencies':
+                    [
+                        'copy_compiler_dll'
+                    ],
+                }],
+                ['angle_build_winrt==1',
+                {
+                    'sources':
+                    [
+                        '<@(angle_libangle_winrt_sources)',
+                    ],
+                    'defines':
+                    [
+                        'NTDDI_VERSION=NTDDI_WINBLUE',
                     ],
-
-                    'configurations':
+                    'msvs_enable_winrt' : '1',
+                    'msvs_requires_importlibrary' : 'true',
+                    'msvs_settings':
                     {
-                        'Debug':
+                        'VCLinkerTool':
                         {
-                            'defines':
+                            'EnableCOMDATFolding': '1',
+                            'OptimizeReferences': '1',
+                        }
+                    },
+                }],
+                ['angle_build_winphone==1',
+                {
+                    'msvs_enable_winphone' : '1',
+                }],
+            ],
+            'configurations':
+            {
+                'Debug_Base':
+                {
+                    'defines':
+                    [
+                        'ANGLE_ENABLE_DEBUG_ANNOTATIONS',
+                        'ANGLE_GENERATE_SHADER_DEBUG_INFO'
+                    ],
+                    'msvs_settings':
+                    {
+                        'VCLinkerTool':
+                        {
+                            'AdditionalDependencies':
                             [
-                                'ANGLE_ENABLE_PERF',
-                            ],
-                            'msvs_settings':
-                            {
-                                'VCLinkerTool':
-                                {
-                                    'AdditionalDependencies':
-                                    [
-                                        'd3d9.lib',
-                                    ]
-                                }
-                            },
-                        },
+                                'd3d9.lib',
+                            ]
+                        }
                     },
                 },
+            },
+        },
+        {
+            'target_name': 'libGLESv2',
+            'type': 'shared_library',
+            'dependencies': [ 'libANGLE' ],
+            'includes': [ '../build/common_defines.gypi', ],
+            'sources':
+            [
+                'libGLESv2/libGLESv2.cpp',
+                'libGLESv2/libGLESv2.def',
+                'libGLESv2/libGLESv2.rc',
+            ],
+            'conditions':
+            [
+                ['angle_build_winrt==1',
                 {
-                    'target_name': 'libGLESv2',
-                    'type': 'shared_library',
-                    'dependencies': [ 'libANGLE' ],
-                    'includes': [ '../build/common_defines.gypi', ],
-                    'sources':
+                    'msvs_enable_winrt' : '1',
+                    'msvs_requires_importlibrary' : 'true',
+                    'msvs_settings':
+                    {
+                        'VCLinkerTool':
+                        {
+                            'EnableCOMDATFolding': '1',
+                            'OptimizeReferences': '1',
+                        }
+                    },
+                }],
+                ['angle_build_winphone==1',
+                {
+                    'msvs_enable_winphone' : '1',
+                }],
+            ],
+            'configurations':
+            {
+                'Debug_Base':
+                {
+                    'defines':
                     [
-                        'libGLESv2/libGLESv2.cpp',
-                        'libGLESv2/libGLESv2.def',
-                        'libGLESv2/libGLESv2.rc',
+                        'ANGLE_ENABLE_DEBUG_ANNOTATIONS',
                     ],
                 },
+            },
+        },
+        {
+            'target_name': 'libGLESv2_static',
+            'type': 'static_library',
+            # make sure we depend on commit_id as a hard dependency, otherwise
+            # we will try to build the static_lib in parallel
+            'dependencies': [ 'libANGLE', 'commit_id' ],
+            'includes': [ '../build/common_defines.gypi', ],
+            'sources':
+            [
+                'libGLESv2/libGLESv2.cpp',
+                'libGLESv2/libGLESv2.rc',
+            ],
+            'conditions':
+            [
+                ['angle_build_winrt==1',
                 {
-                    'target_name': 'libGLESv2_static',
-                    'type': 'static_library',
-                    # make sure we depend on commit_id as a hard dependency, otherwise
-                    # we will try to build the static_lib in parallel
-                    'dependencies': [ 'libANGLE', 'commit_id' ],
-                    'includes': [ '../build/common_defines.gypi', ],
-                    'sources':
-                    [
-                        'libGLESv2/libGLESv2.cpp',
-                        'libGLESv2/libGLESv2.rc',
-                    ],
-                },
+                    'msvs_enable_winrt' : '1',
+                    'msvs_requires_importlibrary' : 'true',
+                    'msvs_settings':
+                    {
+                        'VCLinkerTool':
+                        {
+                            'EnableCOMDATFolding': '1',
+                            'OptimizeReferences': '1',
+                        }
+            },
+                }],
+                ['angle_build_winphone==1',
+                {
+                    'msvs_enable_winphone' : '1',
+                }],
             ],
         },
-        ],
     ],
 }
--- a/gfx/angle/src/libGLESv2/Context.cpp
+++ b/gfx/angle/src/libGLESv2/Context.cpp
@@ -233,25 +233,20 @@ GLuint Context::createTexture()
     return mResourceManager->createTexture();
 }
 
 GLuint Context::createRenderbuffer()
 {
     return mResourceManager->createRenderbuffer();
 }
 
-GLsync Context::createFenceSync(GLenum condition)
+GLsync Context::createFenceSync()
 {
     GLuint handle = mResourceManager->createFenceSync();
 
-    gl::FenceSync *fenceSync = mResourceManager->getFenceSync(handle);
-    ASSERT(fenceSync);
-
-    fenceSync->set(condition);
-
     return reinterpret_cast<GLsync>(handle);
 }
 
 GLuint Context::createVertexArray()
 {
     GLuint handle = mVertexArrayHandleAllocator.allocate();
 
     // Although the spec states VAO state is not initialized until the object is bound,
@@ -285,17 +280,17 @@ GLuint Context::createFramebuffer()
 
     return handle;
 }
 
 GLuint Context::createFenceNV()
 {
     GLuint handle = mFenceNVHandleAllocator.allocate();
 
-    mFenceNVMap[handle] = new FenceNV(mRenderer);
+    mFenceNVMap[handle] = new FenceNV(mRenderer->createFenceNV());
 
     return handle;
 }
 
 // Returns an unused query name
 GLuint Context::createQuery()
 {
     GLuint handle = mQueryHandleAllocator.allocate();
@@ -1469,31 +1464,30 @@ Error Context::applyTextures(ProgramBina
 {
     size_t samplerRange = programBinary->getUsedSamplerRange(shaderType);
     for (size_t samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
     {
         GLenum textureType = programBinary->getSamplerTextureType(shaderType, samplerIndex);
         GLint textureUnit = programBinary->getSamplerMapping(shaderType, samplerIndex, getCaps());
         if (textureUnit != -1)
         {
-            SamplerState sampler;
-            Texture* texture = getSamplerTexture(textureUnit, textureType);
-            texture->getSamplerStateWithNativeOffset(&sampler);
+            Texture *texture = getSamplerTexture(textureUnit, textureType);
+            SamplerState sampler = texture->getSamplerState();
 
             Sampler *samplerObject = mState.getSampler(textureUnit);
             if (samplerObject)
             {
                 samplerObject->getState(&sampler);
             }
 
             // TODO: std::binary_search may become unavailable using older versions of GCC
             if (texture->isSamplerComplete(sampler, mTextureCaps, mExtensions, mClientVersion) &&
                 !std::binary_search(framebufferSerials.begin(), framebufferSerials.begin() + framebufferSerialCount, texture->getTextureSerial()))
             {
-                Error error = mRenderer->setSamplerState(shaderType, samplerIndex, sampler);
+                Error error = mRenderer->setSamplerState(shaderType, samplerIndex, texture, sampler);
                 if (error.isError())
                 {
                     return error;
                 }
 
                 error = mRenderer->setTexture(shaderType, samplerIndex, texture);
                 if (error.isError())
                 {
@@ -1614,17 +1608,21 @@ Error Context::clear(GLbitfield mask)
 {
     if (mState.isRasterizerDiscardEnabled())
     {
         return Error(GL_NO_ERROR);
     }
 
     ClearParameters clearParams = mState.getClearParameters(mask);
 
-    applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
+    Error error = applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
+    if (error.isError())
+    {
+        return error;
+    }
 
     return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
 }
 
 Error Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values)
 {
     if (mState.isRasterizerDiscardEnabled())
     {
@@ -1645,17 +1643,21 @@ Error Context::clearBufferfv(GLenum buff
     }
 
     if (buffer == GL_DEPTH)
     {
         clearParams.clearDepth = true;
         clearParams.depthClearValue = values[0];
     }
 
-    applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
+    Error error = applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
+    if (error.isError())
+    {
+        return error;
+    }
 
     return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
 }
 
 Error Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values)
 {
     if (mState.isRasterizerDiscardEnabled())
     {
@@ -1666,17 +1668,21 @@ Error Context::clearBufferuiv(GLenum buf
     ClearParameters clearParams = mState.getClearParameters(0);
     for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
     {
         clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
     }
     clearParams.colorUIClearValue = ColorUI(values[0], values[1], values[2], values[3]);
     clearParams.colorClearType = GL_UNSIGNED_INT;
 
-    applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
+    Error error = applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
+    if (error.isError())
+    {
+        return error;
+    }
 
     return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
 }
 
 Error Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values)
 {
     if (mState.isRasterizerDiscardEnabled())
     {
@@ -1697,17 +1703,21 @@ Error Context::clearBufferiv(GLenum buff
     }
 
     if (buffer == GL_STENCIL)
     {
         clearParams.clearStencil = true;
         clearParams.stencilClearValue = values[1];
     }
 
-    applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
+    Error error = applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
+    if (error.isError())
+    {
+        return error;
+    }
 
     return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
 }
 
 Error Context::clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil)
 {
     if (mState.isRasterizerDiscardEnabled())
     {
@@ -1716,17 +1726,21 @@ Error Context::clearBufferfi(GLenum buff
 
     // glClearBufferfi can only be called to clear a depth stencil buffer
     ClearParameters clearParams = mState.getClearParameters(0);
     clearParams.clearDepth = true;
     clearParams.depthClearValue = depth;
     clearParams.clearStencil = true;
     clearParams.stencilClearValue = stencil;
 
-    applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
+    Error error = applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
+    if (error.isError())
+    {
+        return error;
+    }
 
     return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
 }
 
 Error Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
                           GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
 {
     Framebuffer *framebuffer = mState.getReadFramebuffer();
@@ -1891,19 +1905,19 @@ Error Context::drawElements(GLenum mode,
             return error;
         }
     }
 
     return Error(GL_NO_ERROR);
 }
 
 // Implements glFlush when block is false, glFinish when block is true
-void Context::sync(bool block)
+Error Context::sync(bool block)
 {
-    mRenderer->sync(block);
+    return mRenderer->sync(block);
 }
 
 void Context::recordError(const Error &error)
 {
     if (error.isError())
     {
         mErrors.insert(error.getCode());
     }
--- a/gfx/angle/src/libGLESv2/Context.h
+++ b/gfx/angle/src/libGLESv2/Context.h
@@ -81,17 +81,17 @@ class Context
     // ResourceManager, which owns these object types
     GLuint createBuffer();
     GLuint createShader(GLenum type);
     GLuint createProgram();
     GLuint createTexture();
     GLuint createRenderbuffer();
     GLuint createSampler();
     GLuint createTransformFeedback();
-    GLsync createFenceSync(GLenum condition);
+    GLsync createFenceSync();
 
     void deleteBuffer(GLuint buffer);
     void deleteShader(GLuint shader);
     void deleteProgram(GLuint program);
     void deleteTexture(GLuint texture);
     void deleteRenderbuffer(GLuint renderbuffer);
     void deleteSampler(GLuint sampler);
     void deleteTransformFeedback(GLuint transformFeedback);
@@ -188,17 +188,17 @@ class Context
     Error clearBufferiv(GLenum buffer, int drawbuffer, const int *values);
     Error clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil);
 
     Error readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);
     Error drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances);
     Error drawElements(GLenum mode, GLsizei count, GLenum type,
                        const GLvoid *indices, GLsizei instances,
                        const rx::RangeUI &indexRange);
-    void sync(bool block);   // flush/finish
+    Error sync(bool block);   // flush/finish
 
     void recordError(const Error &error);
 
     GLenum getError();
     GLenum getResetStatus();
     virtual bool isResetNotificationEnabled();
 
     virtual int getClientVersion() const;
--- a/gfx/angle/src/libGLESv2/Fence.cpp
+++ b/gfx/angle/src/libGLESv2/Fence.cpp
@@ -1,194 +1,116 @@
 //
 // Copyright (c) 2002-2013 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.
 //
 
-// Fence.cpp: Implements the gl::Fence class, which supports the GL_NV_fence extension.
-
-// Important note on accurate timers in Windows:
-//
-// QueryPerformanceCounter has a few major issues, including being 10x as expensive to call
-// as timeGetTime on laptops and "jumping" during certain hardware events.
-//
-// See the comments at the top of the Chromium source file "chromium/src/base/time/time_win.cc"
-//   https://code.google.com/p/chromium/codesearch#chromium/src/base/time/time_win.cc
-//
-// We still opt to use QPC. In the present and moving forward, most newer systems will not suffer
-// from buggy implementations.
+// Fence.cpp: Implements the gl::FenceNV and gl::FenceSync classes, which support the GL_NV_fence
+// extension and GLES3 sync objects.
 
 #include "libGLESv2/Fence.h"
 #include "libGLESv2/renderer/FenceImpl.h"
 #include "libGLESv2/renderer/Renderer.h"
 #include "libGLESv2/main.h"
+#include "common/utilities.h"
 
 #include "angle_gl.h"
 
 namespace gl
 {
 
-FenceNV::FenceNV(rx::Renderer *renderer)
+FenceNV::FenceNV(rx::FenceNVImpl *impl)
+    : mFence(impl),
+      mIsSet(false),
+      mStatus(GL_FALSE),
+      mCondition(GL_NONE)
 {
-    mFence = renderer->createFence();
 }
 
 FenceNV::~FenceNV()
 {
-    delete mFence;
+    SafeDelete(mFence);
 }
 
 GLboolean FenceNV::isFence() const
 {
     // GL_NV_fence spec:
     // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence.
-    return (mFence->isSet() ? GL_TRUE : GL_FALSE);
+    return (mIsSet ? GL_TRUE : GL_FALSE);
 }
 
-void FenceNV::setFence(GLenum condition)
+Error FenceNV::setFence(GLenum condition)
 {
-    mFence->set();
+    Error error = mFence->set();
+    if (error.isError())
+    {
+        return error;
+    }
 
     mCondition = condition;
     mStatus = GL_FALSE;
-}
-
-GLboolean FenceNV::testFence()
-{
-    // Flush the command buffer by default
-    bool result = mFence->test(true);
+    mIsSet = true;
 
-    mStatus = (result ? GL_TRUE : GL_FALSE);
-    return mStatus;
-}
-
-void FenceNV::finishFence()
-{
-    ASSERT(mFence->isSet());
-
-    while (!mFence->test(true))
-    {
-        Sleep(0);
-    }
+    return Error(GL_NO_ERROR);
 }
 
-GLint FenceNV::getFencei(GLenum pname)
+Error FenceNV::testFence(GLboolean *outResult)
 {
-    ASSERT(mFence->isSet());
-
-    switch (pname)
+    // Flush the command buffer by default
+    Error error = mFence->test(true, &mStatus);
+    if (error.isError())
     {
-      case GL_FENCE_STATUS_NV:
-        {
-            // GL_NV_fence spec:
-            // Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV
-            // or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.
-            if (mStatus == GL_TRUE)
-            {
-                return GL_TRUE;
-            }
+        return error;
+    }
 
-            mStatus = (mFence->test(false) ? GL_TRUE : GL_FALSE);
-            return mStatus;
-        }
-
-      case GL_FENCE_CONDITION_NV:
-        return mCondition;
-
-      default: UNREACHABLE(); return 0;
-    }
+    *outResult = mStatus;
+    return Error(GL_NO_ERROR);
 }
 
-FenceSync::FenceSync(rx::Renderer *renderer, GLuint id)
-    : RefCountObject(id)
+Error FenceNV::finishFence()
 {
-    mFence = renderer->createFence();
+    ASSERT(mIsSet);
 
-    LARGE_INTEGER counterFreqency = { 0 };
-    BOOL success = QueryPerformanceFrequency(&counterFreqency);
-    UNUSED_ASSERTION_VARIABLE(success);
-    ASSERT(success);
+    return mFence->finishFence(&mStatus);
+}
 
-    mCounterFrequency = counterFreqency.QuadPart;
+FenceSync::FenceSync(rx::FenceSyncImpl *impl, GLuint id)
+    : RefCountObject(id),
+      mFence(impl),
+      mCondition(GL_NONE)
+{
 }
 
 FenceSync::~FenceSync()
 {
-    delete mFence;
-}
-
-void FenceSync::set(GLenum condition)
-{
-    mCondition = condition;
-    mFence->set();
+    SafeDelete(mFence);
 }
 
-GLenum FenceSync::clientWait(GLbitfield flags, GLuint64 timeout)
+Error FenceSync::set(GLenum condition)
 {
-    ASSERT(mFence->isSet());
-
-    bool flushCommandBuffer = ((flags & GL_SYNC_FLUSH_COMMANDS_BIT) != 0);
-
-    if (mFence->test(flushCommandBuffer))
+    Error error = mFence->set();
+    if (error.isError())
     {
-        return GL_ALREADY_SIGNALED;
-    }
-
-    if (mFence->hasError())
-    {
-        return GL_WAIT_FAILED;
-    }
-
-    if (timeout == 0)
-    {
-        return GL_TIMEOUT_EXPIRED;
+        return error;
     }
 
-    LARGE_INTEGER currentCounter = { 0 };
-    BOOL success = QueryPerformanceCounter(&currentCounter);
-    UNUSED_ASSERTION_VARIABLE(success);
-    ASSERT(success);
-
-    LONGLONG timeoutInSeconds = static_cast<LONGLONG>(timeout) * static_cast<LONGLONG>(1000000ll);
-    LONGLONG endCounter = currentCounter.QuadPart + mCounterFrequency * timeoutInSeconds;
-
-    while (currentCounter.QuadPart < endCounter && !mFence->test(flushCommandBuffer))
-    {
-        Sleep(0);
-        BOOL success = QueryPerformanceCounter(&currentCounter);
-        UNUSED_ASSERTION_VARIABLE(success);
-        ASSERT(success);
-    }
-
-    if (mFence->hasError())
-    {
-        return GL_WAIT_FAILED;
-    }
-
-    if (currentCounter.QuadPart >= endCounter)
-    {
-        return GL_TIMEOUT_EXPIRED;
-    }
-
-    return GL_CONDITION_SATISFIED;
+    mCondition = condition;
+    return Error(GL_NO_ERROR);
 }
 
-void FenceSync::serverWait()
+Error FenceSync::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult)
 {
-    // Because our API is currently designed to be called from a single thread, we don't need to do
-    // extra work for a server-side fence. GPU commands issued after the fence is created will always
-    // be processed after the fence is signaled.
+    ASSERT(mCondition != GL_NONE);
+    return mFence->clientWait(flags, timeout, outResult);
 }
 
-GLenum FenceSync::getStatus() const
+Error FenceSync::serverWait(GLbitfield flags, GLuint64 timeout)
 {
-    if (mFence->test(false))
-    {
-        // The spec does not specify any way to report errors during the status test (e.g. device lost)
-        // so we report the fence is unblocked in case of error or signaled.
-        return GL_SIGNALED;
-    }
+    return mFence->serverWait(flags, timeout);
+}
 
-    return GL_UNSIGNALED;
+Error FenceSync::getStatus(GLint *outResult) const
+{
+    return mFence->getStatus(outResult);
 }
 
 }
--- a/gfx/angle/src/libGLESv2/Fence.h
+++ b/gfx/angle/src/libGLESv2/Fence.h
@@ -1,72 +1,76 @@
 //
 // Copyright (c) 2002-2013 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.
 //
 
-// Fence.h: Defines the gl::Fence class, which supports the GL_NV_fence extension.
+// Fence.h: Defines the gl::FenceNV and gl::FenceSync classes, which support the GL_NV_fence
+// extension and GLES3 sync objects.
 
 #ifndef LIBGLESV2_FENCE_H_
 #define LIBGLESV2_FENCE_H_
 
+#include "libGLESv2/Error.h"
+
 #include "common/angleutils.h"
 #include "common/RefCountObject.h"
 
 namespace rx
 {
 class Renderer;
-class FenceImpl;
+class FenceNVImpl;
+class FenceSyncImpl;
 }
 
 namespace gl
 {
 
 class FenceNV
 {
   public:
-    explicit FenceNV(rx::Renderer *renderer);
+    explicit FenceNV(rx::FenceNVImpl *impl);
     virtual ~FenceNV();
 
     GLboolean isFence() const;
-    void setFence(GLenum condition);
-    GLboolean testFence();
-    void finishFence();
-    GLint getFencei(GLenum pname);
+    Error setFence(GLenum condition);
+    Error testFence(GLboolean *outResult);
+    Error finishFence();
 
     GLboolean getStatus() const { return mStatus; }
     GLuint getCondition() const { return mCondition; }
 
   private:
     DISALLOW_COPY_AND_ASSIGN(FenceNV);
 
-    rx::FenceImpl *mFence;
+    rx::FenceNVImpl *mFence;
+
+    bool mIsSet;
 
     GLboolean mStatus;
     GLenum mCondition;
 };
 
 class FenceSync : public RefCountObject
 {
   public:
-    explicit FenceSync(rx::Renderer *renderer, GLuint id);
+    explicit FenceSync(rx::FenceSyncImpl *impl, GLuint id);
     virtual ~FenceSync();
 
-    void set(GLenum condition);
-    GLenum clientWait(GLbitfield flags, GLuint64 timeout);
-    void serverWait();
-    GLenum getStatus() const;
+    Error set(GLenum condition);
+    Error clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult);
+    Error serverWait(GLbitfield flags, GLuint64 timeout);
+    Error getStatus(GLint *outResult) const;
 
     GLuint getCondition() const { return mCondition; }
 
   private:
     DISALLOW_COPY_AND_ASSIGN(FenceSync);
 
-    rx::FenceImpl *mFence;
-    LONGLONG mCounterFrequency;
+    rx::FenceSyncImpl *mFence;
 
     GLenum mCondition;
 };
 
 }
 
 #endif   // LIBGLESV2_FENCE_H_
--- a/gfx/angle/src/libGLESv2/Framebuffer.cpp
+++ b/gfx/angle/src/libGLESv2/Framebuffer.cpp
@@ -18,33 +18,36 @@
 #include "libGLESv2/renderer/RenderTarget.h"
 #include "libGLESv2/renderer/Workarounds.h"
 #include "libGLESv2/renderer/d3d/TextureD3D.h"
 
 #include "common/utilities.h"
 
 namespace rx
 {
-RenderTarget *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment)
+gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget **outRT)
 {
     if (attachment->isTexture())
     {
         gl::Texture *texture = attachment->getTexture();
         ASSERT(texture);
         TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
         const gl::ImageIndex *index = attachment->getTextureImageIndex();
         ASSERT(index);
-        return textureD3D->getRenderTarget(*index);
+        return textureD3D->getRenderTarget(*index, outRT);
     }
+    else
+    {
+        gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
+        ASSERT(renderbuffer);
 
-    gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
-    ASSERT(renderbuffer);
-
-    // TODO: cast to RenderbufferD3D
-    return renderbuffer->getStorage()->getRenderTarget();
+        // TODO: cast to RenderbufferD3D
+        *outRT = renderbuffer->getStorage()->getRenderTarget();
+        return gl::Error(GL_NO_ERROR);
+    }
 }
 
 // Note: RenderTarget serials should ideally be in the RenderTargets themselves.
 unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment)
 {
     if (attachment->isTexture())
     {
         gl::Texture *texture = attachment->getTexture();
@@ -598,57 +601,71 @@ GLenum Framebuffer::completeness() const
     if (missingAttachment)
     {
         return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
     }
 
     return GL_FRAMEBUFFER_COMPLETE;
 }
 
-void Framebuffer::invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments)
+Error Framebuffer::invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments)
 {
     GLuint maxDimension = caps.maxRenderbufferSize;
-    invalidateSub(caps, numAttachments, attachments, 0, 0, maxDimension, maxDimension);
+    return invalidateSub(numAttachments, attachments, 0, 0, maxDimension, maxDimension);
 }
 
-void Framebuffer::invalidateSub(const Caps &caps, GLsizei numAttachments, const GLenum *attachments,
-                                GLint x, GLint y, GLsizei width, GLsizei height)
+Error Framebuffer::invalidateSub(GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height)
 {
     ASSERT(completeness() == GL_FRAMEBUFFER_COMPLETE);
     for (GLsizei attachIndex = 0; attachIndex < numAttachments; ++attachIndex)
     {
         GLenum attachmentTarget = attachments[attachIndex];
 
-        gl::FramebufferAttachment *attachment =
-            (attachmentTarget == GL_DEPTH_STENCIL_ATTACHMENT) ? getDepthOrStencilbuffer() :
-                                                                getAttachment(attachmentTarget);
+        FramebufferAttachment *attachment = (attachmentTarget == GL_DEPTH_STENCIL_ATTACHMENT) ? getDepthOrStencilbuffer()
+                                                                                              : getAttachment(attachmentTarget);
 
         if (attachment)
         {
-            rx::RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment);
-            if (renderTarget)
+            rx::RenderTarget *renderTarget = NULL;
+            Error error = rx::GetAttachmentRenderTarget(attachment, &renderTarget);
+            if (error.isError())
             {
-                renderTarget->invalidate(x, y, width, height);
+                return error;
             }
+
+            renderTarget->invalidate(x, y, width, height);
         }
     }
+
+    return Error(GL_NO_ERROR);
 }
 
 DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
     : Framebuffer(renderer, 0)
 {
     Renderbuffer *colorRenderbuffer = new Renderbuffer(0, colorbuffer);
     mColorbuffers[0] = new RenderbufferAttachment(GL_BACK, colorRenderbuffer);
 
-    Renderbuffer *depthStencilBuffer = new Renderbuffer(0, depthStencil);
+    GLenum depthStencilActualFormat = depthStencil->getActualFormat();
+    const gl::InternalFormat &depthStencilFormatInfo = GetInternalFormatInfo(depthStencilActualFormat);
+
+    if (depthStencilFormatInfo.depthBits != 0 || depthStencilFormatInfo.stencilBits != 0)
+    {
+        Renderbuffer *depthStencilBuffer = new Renderbuffer(0, depthStencil);
 
-    // Make a new attachment objects to ensure we do not double-delete
-    // See angle issue 686
-    mDepthbuffer = (depthStencilBuffer->getDepthSize() != 0 ? new RenderbufferAttachment(GL_DEPTH_ATTACHMENT, depthStencilBuffer) : NULL);
-    mStencilbuffer = (depthStencilBuffer->getStencilSize() != 0 ? new RenderbufferAttachment(GL_STENCIL_ATTACHMENT, depthStencilBuffer) : NULL);
+        // Make a new attachment objects to ensure we do not double-delete
+        // See angle issue 686
+        mDepthbuffer = (depthStencilFormatInfo.depthBits != 0 ? new RenderbufferAttachment(GL_DEPTH_ATTACHMENT, depthStencilBuffer) : NULL);
+        mStencilbuffer = (depthStencilFormatInfo.stencilBits != 0 ? new RenderbufferAttachment(GL_STENCIL_ATTACHMENT, depthStencilBuffer) : NULL);
+    }
+    else
+    {
+        // This method transfers ownership, so delete the unused storage if we don't keep it.
+        SafeDelete(depthStencil);
+    }
 
     mDrawBufferStates[0] = GL_BACK;
     mReadBufferState = GL_BACK;
 }
 
 int Framebuffer::getSamples() const
 {
     if (completeness() == GL_FRAMEBUFFER_COMPLETE)
--- a/gfx/angle/src/libGLESv2/Framebuffer.h
+++ b/gfx/angle/src/libGLESv2/Framebuffer.h
@@ -5,22 +5,24 @@
 //
 
 // Framebuffer.h: Defines the gl::Framebuffer class. Implements GL framebuffer
 // objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
 
 #ifndef LIBGLESV2_FRAMEBUFFER_H_
 #define LIBGLESV2_FRAMEBUFFER_H_
 
-#include <vector>
+#include "libGLESv2/Error.h"
 
 #include "common/angleutils.h"
 #include "common/RefCountObject.h"
 #include "Constants.h"
 
+#include <vector>
+
 namespace rx
 {
 class Renderer;
 }
 
 namespace gl
 {
 class FramebufferAttachment;
@@ -67,19 +69,18 @@ class Framebuffer
     bool hasEnabledColorAttachment() const;
     bool hasStencil() const;
     int getSamples() const;
     bool usingExtendedDrawBuffers() const;
 
     virtual GLenum completeness() const;
     bool hasValidDepthStencil() const;
 
-    void invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments);
-    void invalidateSub(const Caps &caps, GLsizei numAttachments, const GLenum *attachments,
-                       GLint x, GLint y, GLsizei width, GLsizei height);
+    Error invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments);
+    Error invalidateSub(GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height);
 
     // Use this method to retrieve the color buffer map when doing rendering.
     // It will apply a workaround for poor shader performance on some systems
     // by compacting the list to skip NULL values.
     ColorbufferInfo getColorbuffersForRender() const;
 
   protected:
     rx::Renderer *mRenderer;
@@ -113,14 +114,14 @@ class DefaultFramebuffer : public Frameb
 
 }
 
 namespace rx
 {
 class RenderTarget;
 
 // TODO: place this in FramebufferD3D.h
-RenderTarget *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment);
+gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget **outRT);
 unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment);
 
 }
 
 #endif   // LIBGLESV2_FRAMEBUFFER_H_
--- a/gfx/angle/src/libGLESv2/ProgramBinary.cpp
+++ b/gfx/angle/src/libGLESv2/ProgramBinary.cpp
@@ -22,79 +22,40 @@
 #include "libGLESv2/main.h"
 #include "libGLESv2/Shader.h"
 #include "libGLESv2/Program.h"
 #include "libGLESv2/renderer/ProgramImpl.h"
 #include "libGLESv2/renderer/d3d/ShaderD3D.h"
 #include "libGLESv2/Context.h"
 #include "libGLESv2/Buffer.h"
 #include "common/blocklayout.h"
+#include "common/features.h"
 
 namespace gl
 {
 
 namespace
 {
 
-GLenum GetTextureType(GLenum samplerType)
-{
-    switch (samplerType)
-    {
-      case GL_SAMPLER_2D:
-      case GL_INT_SAMPLER_2D:
-      case GL_UNSIGNED_INT_SAMPLER_2D:
-      case GL_SAMPLER_2D_SHADOW:
-        return GL_TEXTURE_2D;
-      case GL_SAMPLER_3D:
-      case GL_INT_SAMPLER_3D:
-      case GL_UNSIGNED_INT_SAMPLER_3D:
-        return GL_TEXTURE_3D;
-      case GL_SAMPLER_CUBE:
-      case GL_SAMPLER_CUBE_SHADOW:
-        return GL_TEXTURE_CUBE_MAP;
-      case GL_INT_SAMPLER_CUBE:
-      case GL_UNSIGNED_INT_SAMPLER_CUBE:
-        return GL_TEXTURE_CUBE_MAP;
-      case GL_SAMPLER_2D_ARRAY:
-      case GL_INT_SAMPLER_2D_ARRAY:
-      case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
-      case GL_SAMPLER_2D_ARRAY_SHADOW:
-        return GL_TEXTURE_2D_ARRAY;
-      default: UNREACHABLE();
-    }
-
-    return GL_TEXTURE_2D;
-}
-
 unsigned int ParseAndStripArrayIndex(std::string* name)
 {
     unsigned int subscript = GL_INVALID_INDEX;
 
     // Strip any trailing array operator and retrieve the subscript
     size_t open = name->find_last_of('[');
     size_t close = name->find_last_of(']');
     if (open != std::string::npos && close == name->length() - 1)
     {
         subscript = atoi(name->substr(open + 1).c_str());
         name->erase(open);
     }
 
     return subscript;
 }
 
-bool IsRowMajorLayout(const sh::InterfaceBlockField &var)
-{
-    return var.isRowMajorLayout;
-}
-
-bool IsRowMajorLayout(const sh::ShaderVariable &var)
-{
-    return false;
-}
-
 }
 
 VariableLocation::VariableLocation(const std::string &name, unsigned int element, unsigned int index)
     : name(name), element(element), index(index)
 {
 }
 
 LinkedVarying::LinkedVarying()
@@ -113,19 +74,16 @@ LinkResult::LinkResult(bool linkSuccess,
 {
 }
 
 unsigned int ProgramBinary::mCurrentSerial = 1;
 
 ProgramBinary::ProgramBinary(rx::ProgramImpl *impl)
     : RefCountObject(0),
       mProgram(impl),
-      mUsedVertexSamplerRange(0),
-      mUsedPixelSamplerRange(0),
-      mDirtySamplerMapping(true),
       mValidated(false),
       mSerial(issueSerial())
 {
     ASSERT(impl);
 
     for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
     {
         mSemanticIndex[index] = -1;
@@ -169,157 +127,52 @@ int ProgramBinary::getSemanticIndex(int 
     ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS);
 
     return mSemanticIndex[attributeIndex];
 }
 
 // Returns one more than the highest sampler index used.
 GLint ProgramBinary::getUsedSamplerRange(SamplerType type)
 {
-    switch (type)
-    {
-      case SAMPLER_PIXEL:
-        return mUsedPixelSamplerRange;
-      case SAMPLER_VERTEX:
-        return mUsedVertexSamplerRange;
-      default:
-        UNREACHABLE();
-        return 0;
-    }
+    return mProgram->getUsedSamplerRange(type);
 }
 
 bool ProgramBinary::usesPointSize() const
 {
     return mProgram->usesPointSize();
 }
 
 GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerIndex, const Caps &caps)
 {
-    GLint logicalTextureUnit = -1;
-
-    switch (type)
-    {
-      case SAMPLER_PIXEL:
-        ASSERT(samplerIndex < caps.maxTextureImageUnits);
-        if (samplerIndex < mSamplersPS.size() && mSamplersPS[samplerIndex].active)
-        {
-            logicalTextureUnit = mSamplersPS[samplerIndex].logicalTextureUnit;
-        }
-        break;
-      case SAMPLER_VERTEX:
-        ASSERT(samplerIndex < caps.maxVertexTextureImageUnits);
-        if (samplerIndex < mSamplersVS.size() && mSamplersVS[samplerIndex].active)
-        {
-            logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit;
-        }
-        break;
-      default: UNREACHABLE();
-    }
-
-    if (logicalTextureUnit >= 0 && logicalTextureUnit < static_cast<GLint>(caps.maxCombinedTextureImageUnits))
-    {
-        return logicalTextureUnit;
-    }
-
-    return -1;
+    return mProgram->getSamplerMapping(type, samplerIndex, caps);
 }
 
-// Returns the texture type for a given Direct3D 9 sampler type and
-// index (0-15 for the pixel shader and 0-3 for the vertex shader).
 GLenum ProgramBinary::getSamplerTextureType(SamplerType type, unsigned int samplerIndex)
 {
-    switch (type)
-    {
-      case SAMPLER_PIXEL:
-        ASSERT(samplerIndex < mSamplersPS.size());
-        ASSERT(mSamplersPS[samplerIndex].active);
-        return mSamplersPS[samplerIndex].textureType;
-      case SAMPLER_VERTEX:
-        ASSERT(samplerIndex < mSamplersVS.size());
-        ASSERT(mSamplersVS[samplerIndex].active);
-        return mSamplersVS[samplerIndex].textureType;
-      default: UNREACHABLE();
-    }
-
-    return GL_TEXTURE_2D;
+    return mProgram->getSamplerTextureType(type, samplerIndex);
 }
 
 GLint ProgramBinary::getUniformLocation(std::string name)
 {
-    unsigned int subscript = ParseAndStripArrayIndex(&name);
-
-    unsigned int numUniforms = mUniformIndex.size();
-    for (unsigned int location = 0; location < numUniforms; location++)
-    {
-        if (mUniformIndex[location].name == name)
-        {
-            const int index = mUniformIndex[location].index;
-            const bool isArray = mUniforms[index]->isArray();
-
-            if ((isArray && mUniformIndex[location].element == subscript) ||
-                (subscript == GL_INVALID_INDEX))
-            {
-                return location;
-            }
-        }
-    }
-
-    return -1;
+    return mProgram->getUniformLocation(name);
 }
 
 GLuint ProgramBinary::getUniformIndex(std::string name)
 {
-    unsigned int subscript = ParseAndStripArrayIndex(&name);
-
-    // The app is not allowed to specify array indices other than 0 for arrays of basic types
-    if (subscript != 0 && subscript != GL_INVALID_INDEX)
-    {
-        return GL_INVALID_INDEX;
-    }
-
-    unsigned int numUniforms = mUniforms.size();
-    for (unsigned int index = 0; index < numUniforms; index++)
-    {
-        if (mUniforms[index]->name == name)
-        {
-            if (mUniforms[index]->isArray() || subscript == GL_INVALID_INDEX)
-            {
-                return index;
-            }
-        }
-    }
-
-    return GL_INVALID_INDEX;
+    return mProgram->getUniformIndex(name);
 }
 
 GLuint ProgramBinary::getUniformBlockIndex(std::string name)
 {
-    unsigned int subscript = ParseAndStripArrayIndex(&name);
-
-    unsigned int numUniformBlocks = mUniformBlocks.size();
-    for (unsigned int blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++)
-    {
-        const UniformBlock &uniformBlock = *mUniformBlocks[blockIndex];
-        if (uniformBlock.name == name)
-        {
-            const bool arrayElementZero = (subscript == GL_INVALID_INDEX && uniformBlock.elementIndex == 0);
-            if (subscript == uniformBlock.elementIndex || arrayElementZero)
-            {
-                return blockIndex;
-            }
-        }
-    }
-
-    return GL_INVALID_INDEX;
+    return mProgram->getUniformBlockIndex(name);
 }
 
 UniformBlock *ProgramBinary::getUniformBlockByIndex(GLuint blockIndex)
 {
-    ASSERT(blockIndex < mUniformBlocks.size());
-    return mUniformBlocks[blockIndex];
+    return mProgram->getUniformBlockByIndex(blockIndex);
 }
 
 GLint ProgramBinary::getFragDataLocation(const char *name) const
 {
     std::string baseName(name);
     unsigned int arrayIndex;
     arrayIndex = ParseAndStripArrayIndex(&baseName);
 
@@ -346,478 +199,126 @@ const LinkedVarying &ProgramBinary::getT
     return mProgram->getTransformFeedbackLinkedVaryings()[idx];
 }
 
 GLenum ProgramBinary::getTransformFeedbackBufferMode() const
 {
     return mProgram->getTransformFeedbackBufferMode();
 }
 
-template <typename T>
-static inline void SetIfDirty(T *dest, const T& source, bool *dirtyFlag)
-{
-    ASSERT(dest != NULL);
-    ASSERT(dirtyFlag != NULL);
+void ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat *v) {
+    mProgram->setUniform1fv(location, count, v);
+}
 
-    *dirtyFlag = *dirtyFlag || (memcmp(dest, &source, sizeof(T)) != 0);
-    *dest = source;
+void ProgramBinary::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) {
+    mProgram->setUniform2fv(location, count, v);
 }
 
-template <typename T>
-void ProgramBinary::setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType)
-{
-    const int components = VariableComponentCount(targetUniformType);
-    const GLenum targetBoolType = VariableBoolVectorType(targetUniformType);
-
-    LinkedUniform *targetUniform = getUniformByLocation(location);
-
-    int elementCount = targetUniform->elementCount();
-
-    count = std::min(elementCount - (int)mUniformIndex[location].element, count);
-
-    if (targetUniform->type == targetUniformType)
-    {
-        T *target = reinterpret_cast<T*>(targetUniform->data) + mUniformIndex[location].element * 4;
-
-        for (int i = 0; i < count; i++)
-        {
-            T *dest = target + (i * 4);
-            const T *source = v + (i * components);
-
-            for (int c = 0; c < components; c++)
-            {
-                SetIfDirty(dest + c, source[c], &targetUniform->dirty);
-            }
-            for (int c = components; c < 4; c++)
-            {
-                SetIfDirty(dest + c, T(0), &targetUniform->dirty);
-            }
-        }
-    }
-    else if (targetUniform->type == targetBoolType)
-    {
-        GLint *boolParams = reinterpret_cast<GLint*>(targetUniform->data) + mUniformIndex[location].element * 4;
+void ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) {
+    mProgram->setUniform3fv(location, count, v);
+}
 
-        for (int i = 0; i < count; i++)
-        {
-            GLint *dest = boolParams + (i * 4);
-            const T *source = v + (i * components);
-
-            for (int c = 0; c < components; c++)
-            {
-                SetIfDirty(dest + c, (source[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE, &targetUniform->dirty);
-            }
-            for (int c = components; c < 4; c++)
-            {
-                SetIfDirty(dest + c, GL_FALSE, &targetUniform->dirty);
-            }
-        }
-    }
-    else if (IsSampler(targetUniform->type))
-    {
-        ASSERT(targetUniformType == GL_INT);
+void ProgramBinary::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) {
+    mProgram->setUniform4fv(location, count, v);
+}
 
-        GLint *target = reinterpret_cast<GLint*>(targetUniform->data) + mUniformIndex[location].element * 4;
-
-        bool wasDirty = targetUniform->dirty;
-
-        for (int i = 0; i < count; i++)
-        {
-            GLint *dest = target + (i * 4);
-            const GLint *source = reinterpret_cast<const GLint*>(v) + (i * components);
-
-            SetIfDirty(dest + 0, source[0], &targetUniform->dirty);
-            SetIfDirty(dest + 1, 0, &targetUniform->dirty);
-            SetIfDirty(dest + 2, 0, &targetUniform->dirty);
-            SetIfDirty(dest + 3, 0, &targetUniform->dirty);
-        }
-
-        if (!wasDirty && targetUniform->dirty)
-        {
-            mDirtySamplerMapping = true;
-        }
-    }
-    else UNREACHABLE();
+void ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v) {
+    mProgram->setUniform1iv(location, count, v);
 }
 
-void ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat* v)
-{
-    setUniform(location, count, v, GL_FLOAT);
+void ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v) {
+    mProgram->setUniform2iv(location, count, v);
 }
 
-void ProgramBinary::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
-{
-    setUniform(location, count, v, GL_FLOAT_VEC2);
-}
-
-void ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
-{
-    setUniform(location, count, v, GL_FLOAT_VEC3);
-}
-
-void ProgramBinary::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
-{
-    setUniform(location, count, v, GL_FLOAT_VEC4);
+void ProgramBinary::setUniform3iv(GLint location, GLsizei count, const GLint *v) {
+    mProgram->setUniform3iv(location, count, v);
 }
 
-template<typename T>
-bool transposeMatrix(T *target, const GLfloat *value, int targetWidth, int targetHeight, int srcWidth, int srcHeight)
-{
-    bool dirty = false;
-    int copyWidth = std::min(targetHeight, srcWidth);
-    int copyHeight = std::min(targetWidth, srcHeight);
-
-    for (int x = 0; x < copyWidth; x++)
-    {
-        for (int y = 0; y < copyHeight; y++)
-        {
-            SetIfDirty(target + (x * targetWidth + y), static_cast<T>(value[y * srcWidth + x]), &dirty);
-        }
-    }
-    // clear unfilled right side
-    for (int y = 0; y < copyWidth; y++)
-    {
-        for (int x = copyHeight; x < targetWidth; x++)
-        {
-            SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty);
-        }
-    }
-    // clear unfilled bottom.
-    for (int y = copyWidth; y < targetHeight; y++)
-    {
-        for (int x = 0; x < targetWidth; x++)
-        {
-            SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty);
-        }
-    }
-
-    return dirty;
+void ProgramBinary::setUniform4iv(GLint location, GLsizei count, const GLint *v) {
+    mProgram->setUniform4iv(location, count, v);
 }
 
-template<typename T>
-bool expandMatrix(T *target, const GLfloat *value, int targetWidth, int targetHeight, int srcWidth, int srcHeight)
-{
-    bool dirty = false;
-    int copyWidth = std::min(targetWidth, srcWidth);
-    int copyHeight = std::min(targetHeight, srcHeight);
+void ProgramBinary::setUniform1uiv(GLint location, GLsizei count, const GLuint *v) {
+    mProgram->setUniform1uiv(location, count, v);
+}
 
-    for (int y = 0; y < copyHeight; y++)
-    {
-        for (int x = 0; x < copyWidth; x++)
-        {
-            SetIfDirty(target + (y * targetWidth + x), static_cast<T>(value[y * srcWidth + x]), &dirty);
-        }
-    }
-    // clear unfilled right side
-    for (int y = 0; y < copyHeight; y++)
-    {
-        for (int x = copyWidth; x < targetWidth; x++)
-        {
-            SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty);
-        }
-    }
-    // clear unfilled bottom.
-    for (int y = copyHeight; y < targetHeight; y++)
-    {
-        for (int x = 0; x < targetWidth; x++)
-        {
-            SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty);
-        }
-    }
+void ProgramBinary::setUniform2uiv(GLint location, GLsizei count, const GLuint *v) {
+    mProgram->setUniform2uiv(location, count, v);
+}
 
-    return dirty;
+void ProgramBinary::setUniform3uiv(GLint location, GLsizei count, const GLuint *v) {
+    mProgram->setUniform3uiv(location, count, v);
 }
 
-template <int cols, int rows>
-void ProgramBinary::setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType)
-{
-    LinkedUniform *targetUniform = getUniformByLocation(location);
-
-    int elementCount = targetUniform->elementCount();
-
-    count = std::min(elementCount - (int)mUniformIndex[location].element, count);
-    const unsigned int targetMatrixStride = (4 * rows);
-    GLfloat *target = (GLfloat*)(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * targetMatrixStride);
-
-    for (int i = 0; i < count; i++)
-    {
-        // Internally store matrices as transposed versions to accomodate HLSL matrix indexing
-        if (transpose == GL_FALSE)
-        {
-            targetUniform->dirty = transposeMatrix<GLfloat>(target, value, 4, rows, rows, cols) || targetUniform->dirty;
-        }
-        else
-        {
-            targetUniform->dirty = expandMatrix<GLfloat>(target, value, 4, rows, cols, rows) || targetUniform->dirty;
-        }
-        target += targetMatrixStride;
-        value += cols * rows;
-    }
+void ProgramBinary::setUniform4uiv(GLint location, GLsizei count, const GLuint *v) {
+    mProgram->setUniform4uiv(location, count, v);
 }
 
-void ProgramBinary::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-{
-    setUniformMatrixfv<2, 2>(location, count, transpose, value, GL_FLOAT_MAT2);
-}
-
-void ProgramBinary::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-{
-    setUniformMatrixfv<3, 3>(location, count, transpose, value, GL_FLOAT_MAT3);
-}
-
-void ProgramBinary::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-{
-    setUniformMatrixfv<4, 4>(location, count, transpose, value, GL_FLOAT_MAT4);
-}
-
-void ProgramBinary::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-{
-    setUniformMatrixfv<2, 3>(location, count, transpose, value, GL_FLOAT_MAT2x3);
+void ProgramBinary::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
+    mProgram->setUniformMatrix2fv(location, count, transpose, v);
 }
 
-void ProgramBinary::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-{
-    setUniformMatrixfv<3, 2>(location, count, transpose, value, GL_FLOAT_MAT3x2);
-}
-
-void ProgramBinary::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-{
-    setUniformMatrixfv<2, 4>(location, count, transpose, value, GL_FLOAT_MAT2x4);
-}
-
-void ProgramBinary::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-{
-    setUniformMatrixfv<4, 2>(location, count, transpose, value, GL_FLOAT_MAT4x2);
-}
-
-void ProgramBinary::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-{
-    setUniformMatrixfv<3, 4>(location, count, transpose, value, GL_FLOAT_MAT3x4);
-}
-
-void ProgramBinary::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-{
-    setUniformMatrixfv<4, 3>(location, count, transpose, value, GL_FLOAT_MAT4x3);
+void ProgramBinary::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
+    mProgram->setUniformMatrix3fv(location, count, transpose, v);
 }
 
-void ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v)
-{
-    setUniform(location, count, v, GL_INT);
-}
-
-void ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v)
-{
-    setUniform(location, count, v, GL_INT_VEC2);
+void ProgramBinary::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
+    mProgram->setUniformMatrix4fv(location, count, transpose, v);
 }
 
-void ProgramBinary::setUniform3iv(GLint location, GLsizei count, const GLint *v)
-{
-    setUniform(location, count, v, GL_INT_VEC3);
+void ProgramBinary::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
+    mProgram->setUniformMatrix2x3fv(location, count, transpose, v);
 }
 
-void ProgramBinary::setUniform4iv(GLint location, GLsizei count, const GLint *v)
-{
-    setUniform(location, count, v, GL_INT_VEC4);
-}
-
-void ProgramBinary::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
-{
-    setUniform(location, count, v, GL_UNSIGNED_INT);
-}
-
-void ProgramBinary::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
-{
-    setUniform(location, count, v, GL_UNSIGNED_INT_VEC2);
+void ProgramBinary::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
+    mProgram->setUniformMatrix2x4fv(location, count, transpose, v);
 }
 
-void ProgramBinary::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
-{
-    setUniform(location, count, v, GL_UNSIGNED_INT_VEC3);
+void ProgramBinary::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
+    mProgram->setUniformMatrix3x2fv(location, count, transpose, v);
 }
 
-void ProgramBinary::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
-{
-    setUniform(location, count, v, GL_UNSIGNED_INT_VEC4);
+void ProgramBinary::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
+    mProgram->setUniformMatrix3x4fv(location, count, transpose, v);
+}
+
+void ProgramBinary::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
+    mProgram->setUniformMatrix4x2fv(location, count, transpose, v);
 }
 
-template <typename T>
-void ProgramBinary::getUniformv(GLint location, T *params, GLenum uniformType)
-{
-    LinkedUniform *targetUniform = mUniforms[mUniformIndex[location].index];
-
-    if (IsMatrixType(targetUniform->type))
-    {
-        const int rows = VariableRowCount(targetUniform->type);
-        const int cols = VariableColumnCount(targetUniform->type);
-        transposeMatrix(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4 * rows, rows, cols, 4, rows);
-    }
-    else if (uniformType == VariableComponentType(targetUniform->type))
-    {
-        unsigned int size = VariableComponentCount(targetUniform->type);
-        memcpy(params, targetUniform->data + mUniformIndex[location].element * 4 * sizeof(T),
-                size * sizeof(T));
-    }
-    else
-    {
-        unsigned int size = VariableComponentCount(targetUniform->type);
-        switch (VariableComponentType(targetUniform->type))
-        {
-          case GL_BOOL:
-            {
-                GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
-
-                for (unsigned int i = 0; i < size; i++)
-                {
-                    params[i] = (boolParams[i] == GL_FALSE) ? static_cast<T>(0) : static_cast<T>(1);
-                }
-            }
-            break;
-
-          case GL_FLOAT:
-            {
-                GLfloat *floatParams = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
-
-                for (unsigned int i = 0; i < size; i++)
-                {
-                    params[i] = static_cast<T>(floatParams[i]);
-                }
-            }
-            break;
-
-          case GL_INT:
-            {
-                GLint *intParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
-
-                for (unsigned int i = 0; i < size; i++)
-                {
-                    params[i] = static_cast<T>(intParams[i]);
-                }
-            }
-            break;
-
-          case GL_UNSIGNED_INT:
-            {
-                GLuint *uintParams = (GLuint*)targetUniform->data + mUniformIndex[location].element * 4;
-
-                for (unsigned int i = 0; i < size; i++)
-                {
-                    params[i] = static_cast<T>(uintParams[i]);
-                }
-            }
-            break;
-
-          default: UNREACHABLE();
-        }
-    }
+void ProgramBinary::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
+    mProgram->setUniformMatrix4x3fv(location, count, transpose, v);
 }
 
-void ProgramBinary::getUniformfv(GLint location, GLfloat *params)
-{
-    getUniformv(location, params, GL_FLOAT);
-}
-
-void ProgramBinary::getUniformiv(GLint location, GLint *params)
-{
-    getUniformv(location, params, GL_INT);
+void ProgramBinary::getUniformfv(GLint location, GLfloat *v) {
+    mProgram->getUniformfv(location, v);
 }
 
-void ProgramBinary::getUniformuiv(GLint location, GLuint *params)
-{
-    getUniformv(location, params, GL_UNSIGNED_INT);
+void ProgramBinary::getUniformiv(GLint location, GLint *v) {
+    mProgram->getUniformiv(location, v);
 }
 
-void ProgramBinary::dirtyAllUniforms()
-{
-    unsigned int numUniforms = mUniforms.size();
-    for (unsigned int index = 0; index < numUniforms; index++)
-    {
-        mUniforms[index]->dirty = true;
-    }
+void ProgramBinary::getUniformuiv(GLint location, GLuint *v) {
+    mProgram->getUniformuiv(location, v);
 }
 
 void ProgramBinary::updateSamplerMapping()
 {
-    if (!mDirtySamplerMapping)
-    {
-        return;
-    }
-
-    mDirtySamplerMapping = false;
-
-    // Retrieve sampler uniform values
-    for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
-    {
-        LinkedUniform *targetUniform = mUniforms[uniformIndex];
-
-        if (targetUniform->dirty)
-        {
-            if (IsSampler(targetUniform->type))
-            {
-                int count = targetUniform->elementCount();
-                GLint (*v)[4] = reinterpret_cast<GLint(*)[4]>(targetUniform->data);
-
-                if (targetUniform->isReferencedByFragmentShader())
-                {
-                    unsigned int firstIndex = targetUniform->psRegisterIndex;
-
-                    for (int i = 0; i < count; i++)
-                    {
-                        unsigned int samplerIndex = firstIndex + i;
-
-                        if (samplerIndex < mSamplersPS.size())
-                        {
-                            ASSERT(mSamplersPS[samplerIndex].active);
-                            mSamplersPS[samplerIndex].logicalTextureUnit = v[i][0];
-                        }
-                    }
-                }
-
-                if (targetUniform->isReferencedByVertexShader())
-                {
-                    unsigned int firstIndex = targetUniform->vsRegisterIndex;
-
-                    for (int i = 0; i < count; i++)
-                    {
-                        unsigned int samplerIndex = firstIndex + i;
-
-                        if (samplerIndex < mSamplersVS.size())
-                        {
-                            ASSERT(mSamplersVS[samplerIndex].active);
-                            mSamplersVS[samplerIndex].logicalTextureUnit = v[i][0];
-                        }
-                    }
-                }
-            }
-        }
-    }
+    return mProgram->updateSamplerMapping();
 }
 
 // Applies all the uniforms set for this program object to the renderer
 Error ProgramBinary::applyUniforms()
 {
-    updateSamplerMapping();
-
-    Error error = mProgram->applyUniforms(mUniforms);
-    if (error.isError())
-    {
-        return error;
-    }
-
-    for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
-    {
-        mUniforms[uniformIndex]->dirty = false;
-    }
-
-    return gl::Error(GL_NO_ERROR);
+    return mProgram->applyUniforms();
 }
 
 Error ProgramBinary::applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers, const Caps &caps)
 {
-    ASSERT(boundBuffers.size() == mUniformBlocks.size());
-    return mProgram->applyUniformBuffers(mUniformBlocks, boundBuffers, caps);
+    return mProgram->applyUniformBuffers(boundBuffers, caps);
 }
 
 bool ProgramBinary::linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *vertexShader)
 {
     std::vector<PackedVarying> &fragmentVaryings = fragmentShader->getVaryings();
     std::vector<PackedVarying> &vertexVaryings = vertexShader->getVaryings();
 
     for (size_t fragVaryingIndex = 0; fragVaryingIndex < fragmentVaryings.size(); fragVaryingIndex++)
@@ -857,17 +358,17 @@ bool ProgramBinary::linkVaryings(InfoLog
         }
     }
 
     return true;
 }
 
 LinkResult ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length)
 {
-#ifdef ANGLE_DISABLE_PROGRAM_BINARY_LOAD
+#if ANGLE_PROGRAM_BINARY_LOAD == ANGLE_ENABLED
     return LinkResult(false, Error(GL_NO_ERROR));
 #else
     ASSERT(binaryFormat == mProgram->getBinaryFormat());
 
     reset();
 
     BinaryInputStream stream(binary, length);
 
@@ -907,125 +408,24 @@ LinkResult ProgramBinary::load(InfoLog &
         stream.readString(&mLinkedAttribute[i].name);
         stream.readInt(&mProgram->getShaderAttributes()[i].type);
         stream.readString(&mProgram->getShaderAttributes()[i].name);
         stream.readInt(&mSemanticIndex[i]);
     }
 
     initAttributesByLayout();
 
-    const unsigned int psSamplerCount = stream.readInt<unsigned int>();
-    for (unsigned int i = 0; i < psSamplerCount; ++i)
-    {
-        Sampler sampler;
-        stream.readBool(&sampler.active);
-        stream.readInt(&sampler.logicalTextureUnit);
-        stream.readInt(&sampler.textureType);
-        mSamplersPS.push_back(sampler);
-    }
-    const unsigned int vsSamplerCount = stream.readInt<unsigned int>();
-    for (unsigned int i = 0; i < vsSamplerCount; ++i)
-    {
-        Sampler sampler;
-        stream.readBool(&sampler.active);
-        stream.readInt(&sampler.logicalTextureUnit);
-        stream.readInt(&sampler.textureType);
-        mSamplersVS.push_back(sampler);
-    }
-
-    stream.readInt(&mUsedVertexSamplerRange);
-    stream.readInt(&mUsedPixelSamplerRange);
-
-    const unsigned int uniformCount = stream.readInt<unsigned int>();
-    if (stream.error())
-    {
-        infoLog.append("Invalid program binary.");
-        return LinkResult(false, Error(GL_NO_ERROR));
-    }
-
-    mUniforms.resize(uniformCount);
-    for (unsigned int uniformIndex = 0; uniformIndex < uniformCount; uniformIndex++)
-    {
-        GLenum type = stream.readInt<GLenum>();
-        GLenum precision = stream.readInt<GLenum>();
-        std::string name = stream.readString();
-        unsigned int arraySize = stream.readInt<unsigned int>();
-        int blockIndex = stream.readInt<int>();
-
-        int offset = stream.readInt<int>();
-        int arrayStride = stream.readInt<int>();
-        int matrixStride = stream.readInt<int>();
-        bool isRowMajorMatrix = stream.readBool();
-
-        const sh::BlockMemberInfo blockInfo(offset, arrayStride, matrixStride, isRowMajorMatrix);
-
-        LinkedUniform *uniform = new LinkedUniform(type, precision, name, arraySize, blockIndex, blockInfo);
-
-        stream.readInt(&uniform->psRegisterIndex);
-        stream.readInt(&uniform->vsRegisterIndex);
-        stream.readInt(&uniform->registerCount);
-        stream.readInt(&uniform->registerElement);
-
-        mUniforms[uniformIndex] = uniform;
-    }
-
-    unsigned int uniformBlockCount = stream.readInt<unsigned int>();
-    if (stream.error())
-    {
-        infoLog.append("Invalid program binary.");
-        return LinkResult(false, Error(GL_NO_ERROR));
-    }
-
-    mUniformBlocks.resize(uniformBlockCount);
-    for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlockCount; ++uniformBlockIndex)
-    {
-        std::string name = stream.readString();
-        unsigned int elementIndex = stream.readInt<unsigned int>();
-        unsigned int dataSize = stream.readInt<unsigned int>();
-
-        UniformBlock *uniformBlock = new UniformBlock(name, elementIndex, dataSize);
-
-        stream.readInt(&uniformBlock->psRegisterIndex);
-        stream.readInt(&uniformBlock->vsRegisterIndex);
-
-        unsigned int numMembers = stream.readInt<unsigned int>();
-        uniformBlock->memberUniformIndexes.resize(numMembers);
-        for (unsigned int blockMemberIndex = 0; blockMemberIndex < numMembers; blockMemberIndex++)
-        {
-            stream.readInt(&uniformBlock->memberUniformIndexes[blockMemberIndex]);
-        }
-
-        mUniformBlocks[uniformBlockIndex] = uniformBlock;
-    }
-
-    const unsigned int uniformIndexCount = stream.readInt<unsigned int>();
-    if (stream.error())
-    {
-        infoLog.append("Invalid program binary.");
-        return LinkResult(false, Error(GL_NO_ERROR));
-    }
-
-    mUniformIndex.resize(uniformIndexCount);
-    for (unsigned int uniformIndexIndex = 0; uniformIndexIndex < uniformIndexCount; uniformIndexIndex++)
-    {
-        stream.readString(&mUniformIndex[uniformIndexIndex].name);
-        stream.readInt(&mUniformIndex[uniformIndexIndex].element);
-        stream.readInt(&mUniformIndex[uniformIndexIndex].index);
-    }
-
     LinkResult result = mProgram->load(infoLog, &stream);
     if (result.error.isError() || !result.linkSuccess)
     {
         return result;
     }
 
-    mProgram->initializeUniformStorage(mUniforms);
-
     return LinkResult(true, Error(GL_NO_ERROR));
-#endif // #ifdef ANGLE_DISABLE_PROGRAM_BINARY_LOAD
+#endif // #if ANGLE_PROGRAM_BINARY_LOAD == ANGLE_ENABLED
 }
 
 Error ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length)
 {
     if (binaryFormat)
     {
         *binaryFormat = mProgram->getBinaryFormat();
     }
@@ -1042,84 +442,16 @@ Error ProgramBinary::save(GLenum *binary
     {
         stream.writeInt(mLinkedAttribute[i].type);
         stream.writeString(mLinkedAttribute[i].name);
         stream.writeInt(mProgram->getShaderAttributes()[i].type);
         stream.writeString(mProgram->getShaderAttributes()[i].name);
         stream.writeInt(mSemanticIndex[i]);
     }
 
-    stream.writeInt(mSamplersPS.size());
-    for (unsigned int i = 0; i < mSamplersPS.size(); ++i)
-    {
-        stream.writeInt(mSamplersPS[i].active);
-        stream.writeInt(mSamplersPS[i].logicalTextureUnit);
-        stream.writeInt(mSamplersPS[i].textureType);
-    }
-
-    stream.writeInt(mSamplersVS.size());
-    for (unsigned int i = 0; i < mSamplersVS.size(); ++i)
-    {
-        stream.writeInt(mSamplersVS[i].active);
-        stream.writeInt(mSamplersVS[i].logicalTextureUnit);
-        stream.writeInt(mSamplersVS[i].textureType);
-    }
-
-    stream.writeInt(mUsedVertexSamplerRange);
-    stream.writeInt(mUsedPixelSamplerRange);
-
-    stream.writeInt(mUniforms.size());
-    for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); ++uniformIndex)
-    {
-        const LinkedUniform &uniform = *mUniforms[uniformIndex];
-
-        stream.writeInt(uniform.type);
-        stream.writeInt(uniform.precision);
-        stream.writeString(uniform.name);
-        stream.writeInt(uniform.arraySize);
-        stream.writeInt(uniform.blockIndex);
-
-        stream.writeInt(uniform.blockInfo.offset);
-        stream.writeInt(uniform.blockInfo.arrayStride);
-        stream.writeInt(uniform.blockInfo.matrixStride);
-        stream.writeInt(uniform.blockInfo.isRowMajorMatrix);
-
-        stream.writeInt(uniform.psRegisterIndex);
-        stream.writeInt(uniform.vsRegisterIndex);
-        stream.writeInt(uniform.registerCount);
-        stream.writeInt(uniform.registerElement);
-    }
-
-    stream.writeInt(mUniformBlocks.size());
-    for (size_t uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); ++uniformBlockIndex)
-    {
-        const UniformBlock& uniformBlock = *mUniformBlocks[uniformBlockIndex];
-
-        stream.writeString(uniformBlock.name);
-        stream.writeInt(uniformBlock.elementIndex);
-        stream.writeInt(uniformBlock.dataSize);
-
-        stream.writeInt(uniformBlock.memberUniformIndexes.size());
-        for (unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++)
-        {
-            stream.writeInt(uniformBlock.memberUniformIndexes[blockMemberIndex]);
-        }
-
-        stream.writeInt(uniformBlock.psRegisterIndex);
-        stream.writeInt(uniformBlock.vsRegisterIndex);
-    }
-
-    stream.writeInt(mUniformIndex.size());
-    for (size_t i = 0; i < mUniformIndex.size(); ++i)
-    {
-        stream.writeString(mUniformIndex[i].name);
-        stream.writeInt(mUniformIndex[i].element);
-        stream.writeInt(mUniformIndex[i].index);
-    }
-
     mProgram->save(&stream);
 
     GLsizei streamLength = stream.length();
     const void *streamData = stream.data();
 
     if (streamLength > bufSize)
     {
         if (length)
@@ -1175,51 +507,35 @@ LinkResult ProgramBinary::link(InfoLog &
     if (!vertexShader || !vertexShader->isCompiled())
     {
         return LinkResult(false, Error(GL_NO_ERROR));
     }
     ASSERT(vertexShader->getType() == GL_VERTEX_SHADER);
 
     reset();
 
-    mSamplersPS.resize(caps.maxTextureImageUnits);
-    mSamplersVS.resize(caps.maxVertexTextureImageUnits);
-
-    rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
-    rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
-
     int registers;
     std::vector<LinkedVarying> linkedVaryings;
     LinkResult result = mProgram->link(infoLog, fragmentShader, vertexShader, transformFeedbackVaryings, transformFeedbackBufferMode,
                                        &registers, &linkedVaryings, &mOutputVariables, caps);
     if (result.error.isError() || !result.linkSuccess)
     {
         return result;
     }
 
     if (!linkAttributes(infoLog, attributeBindings, vertexShader))
     {
         return LinkResult(false, Error(GL_NO_ERROR));
     }
 
-    if (!linkUniforms(infoLog, *vertexShader, *fragmentShader, caps))
+    if (!mProgram->linkUniforms(infoLog, *vertexShader, *fragmentShader, caps))
     {
         return LinkResult(false, Error(GL_NO_ERROR));
     }
 
-    // special case for gl_DepthRange, the only built-in uniform (also a struct)
-    if (vertexShaderD3D->usesDepthRange() || fragmentShaderD3D->usesDepthRange())
-    {
-        const sh::BlockMemberInfo &defaultInfo = sh::BlockMemberInfo::getDefaultBlockInfo();
-
-        mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.near", 0, -1, defaultInfo));
-        mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.far", 0, -1, defaultInfo));
-        mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.diff", 0, -1, defaultInfo));
-    }
-
     if (!linkUniformBlocks(infoLog, *vertexShader, *fragmentShader, caps))
     {
         return LinkResult(false, Error(GL_NO_ERROR));
     }
 
     if (!gatherTransformFeedbackLinkedVaryings(infoLog, linkedVaryings, transformFeedbackVaryings,
                                                transformFeedbackBufferMode, &mProgram->getTransformFeedbackLinkedVaryings(), caps))
     {
@@ -1234,16 +550,124 @@ LinkResult ProgramBinary::link(InfoLog &
         infoLog.append("Failed to create D3D shaders.");
         reset();
         return result;
     }
 
     return LinkResult(true, Error(GL_NO_ERROR));
 }
 
+bool ProgramBinary::linkUniformBlocks(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader,
+                                   const gl::Caps &caps)
+{
+    const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks = vertexShader.getInterfaceBlocks();
+    const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks = fragmentShader.getInterfaceBlocks();
+
+    // Check that interface blocks defined in the vertex and fragment shaders are identical
+    typedef std::map<std::string, const sh::InterfaceBlock*> UniformBlockMap;
+    UniformBlockMap linkedUniformBlocks;
+
+    for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++)
+    {
+        const sh::InterfaceBlock &vertexInterfaceBlock = vertexInterfaceBlocks[blockIndex];
+        linkedUniformBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock;
+    }
+
+    for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++)
+    {
+        const sh::InterfaceBlock &fragmentInterfaceBlock = fragmentInterfaceBlocks[blockIndex];
+        UniformBlockMap::const_iterator entry = linkedUniformBlocks.find(fragmentInterfaceBlock.name);
+        if (entry != linkedUniformBlocks.end())
+        {
+            const sh::InterfaceBlock &vertexInterfaceBlock = *entry->second;
+            if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock))
+            {
+                return false;
+            }
+        }
+    }
+
+    for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++)
+    {
+        const sh::InterfaceBlock &interfaceBlock = vertexInterfaceBlocks[blockIndex];
+
+        // Note: shared and std140 layouts are always considered active
+        if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
+        {
+            if (!mProgram->defineUniformBlock(infoLog, vertexShader, interfaceBlock, caps))
+            {
+                return false;
+            }
+        }
+    }
+
+    for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++)
+    {
+        const sh::InterfaceBlock &interfaceBlock = fragmentInterfaceBlocks[blockIndex];
+
+        // Note: shared and std140 layouts are always considered active
+        if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
+        {
+            if (!mProgram->defineUniformBlock(infoLog, fragmentShader, interfaceBlock, caps))
+            {
+                return false;
+            }
+        }
+    }
+
+    return true;
+}
+
+bool ProgramBinary::areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock,
+                                            const sh::InterfaceBlock &fragmentInterfaceBlock)
+{
+    const char* blockName = vertexInterfaceBlock.name.c_str();
+
+    // validate blocks for the same member types
+    if (vertexInterfaceBlock.fields.size() != fragmentInterfaceBlock.fields.size())
+    {
+        infoLog.append("Types for interface block '%s' differ between vertex and fragment shaders", blockName);
+        return false;
+    }
+
+    if (vertexInterfaceBlock.arraySize != fragmentInterfaceBlock.arraySize)
+    {
+        infoLog.append("Array sizes differ for interface block '%s' between vertex and fragment shaders", blockName);
+        return false;
+    }
+
+    if (vertexInterfaceBlock.layout != fragmentInterfaceBlock.layout || vertexInterfaceBlock.isRowMajorLayout != fragmentInterfaceBlock.isRowMajorLayout)
+    {
+        infoLog.append("Layout qualifiers differ for interface block '%s' between vertex and fragment shaders", blockName);
+        return false;
+    }
+
+    const unsigned int numBlockMembers = vertexInterfaceBlock.fields.size();
+    for (unsigned int blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++)
+    {
+        const sh::InterfaceBlockField &vertexMember = vertexInterfaceBlock.fields[blockMemberIndex];
+        const sh::InterfaceBlockField &fragmentMember = fragmentInterfaceBlock.fields[blockMemberIndex];
+
+        if (vertexMember.name != fragmentMember.name)
+        {
+            infoLog.append("Name mismatch for field %d of interface block '%s': (in vertex: '%s', in fragment: '%s')",
+                           blockMemberIndex, blockName, vertexMember.name.c_str(), fragmentMember.name.c_str());
+            return false;
+        }
+
+        std::string memberName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'";
+        if (!gl::ProgramBinary::linkValidateInterfaceBlockFields(infoLog, memberName, vertexMember, fragmentMember))
+        {
+            return false;
+        }
+    }
+
+    return true;
+}
+
 // Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices
 bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, const Shader *vertexShader)
 {
     const rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
 
     unsigned int usedLocations = 0;
     const std::vector<sh::Attribute> &shaderAttributes = vertexShader->getActiveAttributes();
 
@@ -1419,356 +843,16 @@ bool ProgramBinary::linkValidateInterfac
     {
         infoLog.append("Matrix packings for %s differ between vertex and fragment shaders", uniformName.c_str());
         return false;
     }
 
     return true;
 }
 
-bool ProgramBinary::linkUniforms(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps)
-{
-    const rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader.getImplementation());
-    const rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader.getImplementation());
-
-    const std::vector<sh::Uniform> &vertexUniforms = vertexShader.getUniforms();
-    const std::vector<sh::Uniform> &fragmentUniforms = fragmentShader.getUniforms();
-
-    // Check that uniforms defined in the vertex and fragment shaders are identical
-    typedef std::map<std::string, const sh::Uniform*> UniformMap;
-    UniformMap linkedUniforms;
-
-    for (unsigned int vertexUniformIndex = 0; vertexUniformIndex < vertexUniforms.size(); vertexUniformIndex++)
-    {
-        const sh::Uniform &vertexUniform = vertexUniforms[vertexUniformIndex];
-        linkedUniforms[vertexUniform.name] = &vertexUniform;
-    }
-
-    for (unsigned int fragmentUniformIndex = 0; fragmentUniformIndex < fragmentUniforms.size(); fragmentUniformIndex++)
-    {
-        const sh::Uniform &fragmentUniform = fragmentUniforms[fragmentUniformIndex];
-        UniformMap::const_iterator entry = linkedUniforms.find(fragmentUniform.name);
-        if (entry != linkedUniforms.end())
-        {
-            const sh::Uniform &vertexUniform = *entry->second;
-            const std::string &uniformName = "uniform '" + vertexUniform.name + "'";
-            if (!linkValidateUniforms(infoLog, uniformName, vertexUniform, fragmentUniform))
-            {
-                return false;
-            }
-        }
-    }
-
-    for (unsigned int uniformIndex = 0; uniformIndex < vertexUniforms.size(); uniformIndex++)
-    {
-        const sh::Uniform &uniform = vertexUniforms[uniformIndex];
-
-        if (uniform.staticUse)
-        {
-            defineUniformBase(GL_VERTEX_SHADER, uniform, vertexShaderD3D->getUniformRegister(uniform.name));
-        }
-    }
-
-    for (unsigned int uniformIndex = 0; uniformIndex < fragmentUniforms.size(); uniformIndex++)
-    {
-        const sh::Uniform &uniform = fragmentUniforms[uniformIndex];
-
-        if (uniform.staticUse)
-        {
-            defineUniformBase(GL_FRAGMENT_SHADER, uniform, fragmentShaderD3D->getUniformRegister(uniform.name));
-        }
-    }
-
-    if (!indexUniforms(infoLog, caps))
-    {
-        return false;
-    }
-
-    mProgram->initializeUniformStorage(mUniforms);
-
-    return true;
-}
-
-void ProgramBinary::defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister)
-{
-    ShShaderOutput outputType = rx::ShaderD3D::getCompilerOutputType(shader);
-    sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType));
-    encoder.skipRegisters(uniformRegister);
-
-    defineUniform(shader, uniform, uniform.name, &encoder);
-}
-
-void ProgramBinary::defineUniform(GLenum shader, const sh::ShaderVariable &uniform,
-                                  const std::string &fullName, sh::HLSLBlockEncoder *encoder)
-{
-    if (uniform.isStruct())
-    {
-        for (unsigned int elementIndex = 0; elementIndex < uniform.elementCount(); elementIndex++)
-        {
-            const std::string &elementString = (uniform.isArray() ? ArrayString(elementIndex) : "");
-
-            encoder->enterAggregateType();
-
-            for (size_t fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++)
-            {
-                const sh::ShaderVariable &field = uniform.fields[fieldIndex];
-                const std::string &fieldFullName = (fullName + elementString + "." + field.name);
-
-                defineUniform(shader, field, fieldFullName, encoder);
-            }
-
-            encoder->exitAggregateType();
-        }
-    }
-    else // Not a struct
-    {
-        // Arrays are treated as aggregate types
-        if (uniform.isArray())
-        {
-            encoder->enterAggregateType();
-        }
-
-        LinkedUniform *linkedUniform = getUniformByName(fullName);
-
-        if (!linkedUniform)
-        {
-            linkedUniform = new LinkedUniform(uniform.type, uniform.precision, fullName, uniform.arraySize,
-                                              -1, sh::BlockMemberInfo::getDefaultBlockInfo());
-            ASSERT(linkedUniform);
-            linkedUniform->registerElement = encoder->getCurrentElement();
-            mUniforms.push_back(linkedUniform);
-        }
-
-        ASSERT(linkedUniform->registerElement == encoder->getCurrentElement());
-
-        if (shader == GL_FRAGMENT_SHADER)
-        {
-            linkedUniform->psRegisterIndex = encoder->getCurrentRegister();
-        }
-        else if (shader == GL_VERTEX_SHADER)
-        {
-            linkedUniform->vsRegisterIndex = encoder->getCurrentRegister();
-        }
-        else UNREACHABLE();
-
-        // Advance the uniform offset, to track registers allocation for structs
-        encoder->encodeType(uniform.type, uniform.arraySize, false);
-
-        // Arrays are treated as aggregate types
-        if (uniform.isArray())
-        {
-            encoder->exitAggregateType();
-        }
-    }
-}
-
-bool ProgramBinary::indexSamplerUniform(const LinkedUniform &uniform, InfoLog &infoLog, const Caps &caps)
-{
-    ASSERT(IsSampler(uniform.type));
-    ASSERT(uniform.vsRegisterIndex != GL_INVALID_INDEX || uniform.psRegisterIndex != GL_INVALID_INDEX);
-
-    if (uniform.vsRegisterIndex != GL_INVALID_INDEX)
-    {
-        if (!assignSamplers(uniform.vsRegisterIndex, uniform.type, uniform.arraySize, mSamplersVS,
-                            &mUsedVertexSamplerRange))
-        {
-            infoLog.append("Vertex shader sampler count exceeds the maximum vertex texture units (%d).",
-                           mSamplersVS.size());
-            return false;
-        }
-
-        unsigned int maxVertexVectors = mProgram->getReservedUniformVectors(GL_VERTEX_SHADER) + caps.maxVertexUniformVectors;
-        if (uniform.vsRegisterIndex + uniform.registerCount > maxVertexVectors)
-        {
-            infoLog.append("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%u)",
-                           caps.maxVertexUniformVectors);
-            return false;
-        }
-    }
-
-    if (uniform.psRegisterIndex != GL_INVALID_INDEX)
-    {
-        if (!assignSamplers(uniform.psRegisterIndex, uniform.type, uniform.arraySize, mSamplersPS,
-                            &mUsedPixelSamplerRange))
-        {
-            infoLog.append("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).",
-                           mSamplersPS.size());
-            return false;
-        }
-
-        unsigned int maxFragmentVectors = mProgram->getReservedUniformVectors(GL_FRAGMENT_SHADER) + caps.maxFragmentUniformVectors;
-        if (uniform.psRegisterIndex + uniform.registerCount > maxFragmentVectors)
-        {
-            infoLog.append("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%u)",
-                           caps.maxFragmentUniformVectors);
-            return false;
-        }
-    }
-
-    return true;
-}
-
-bool ProgramBinary::indexUniforms(InfoLog &infoLog, const Caps &caps)
-{
-    for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
-    {
-        const LinkedUniform &uniform = *mUniforms[uniformIndex];
-
-        if (IsSampler(uniform.type))
-        {
-            if (!indexSamplerUniform(uniform, infoLog, caps))
-            {
-                return false;
-            }
-        }
-
-        for (unsigned int arrayElementIndex = 0; arrayElementIndex < uniform.elementCount(); arrayElementIndex++)
-        {
-            mUniformIndex.push_back(VariableLocation(uniform.name, arrayElementIndex, uniformIndex));
-        }
-    }
-
-    return true;
-}
-
-bool ProgramBinary::assignSamplers(unsigned int startSamplerIndex,
-                                   GLenum samplerType,
-                                   unsigned int samplerCount,
-                                   std::vector<Sampler> &outSamplers,
-                                   GLuint *outUsedRange)
-{
-    unsigned int samplerIndex = startSamplerIndex;
-
-    do
-    {
-        if (samplerIndex < outSamplers.size())
-        {
-            Sampler& sampler = outSamplers[samplerIndex];
-            sampler.active = true;
-            sampler.textureType = GetTextureType(samplerType);
-            sampler.logicalTextureUnit = 0;
-            *outUsedRange = std::max(samplerIndex + 1, *outUsedRange);
-        }
-        else
-        {
-            return false;
-        }
-
-        samplerIndex++;
-    } while (samplerIndex < startSamplerIndex + samplerCount);
-
-    return true;
-}
-
-bool ProgramBinary::areMatchingInterfaceBlocks(InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, const sh::InterfaceBlock &fragmentInterfaceBlock)
-{
-    const char* blockName = vertexInterfaceBlock.name.c_str();