Merge inbound to mozilla-central. a=merge
authorTiberius Oros <toros@mozilla.com>
Thu, 11 Oct 2018 06:54:10 +0300
changeset 496401 e4220fa7a191903a814e8cf473cf544fe9762625
parent 496377 b89a744deccb5be6113036d95c5c208e1ae2b59f (current diff)
parent 496400 4f27d46e7abeafce27a74ce0282257a3889572cc (diff)
child 496407 bd701f1b3cf8762d27966a94951d9825a1b30b4f
child 496444 777ef3d920f01a85b677dea8914fc38df9135814
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to mozilla-central. a=merge
browser/components/places/tests/browser/browser_bookmarkProperties_addLivemark.js
dom/canvas/WebGLExtensionCompressedTextureATC.cpp
dom/canvas/test/webgl-mochitest/ensure-exts/test_WEBGL_compressed_texture_atc.html
dom/canvas/test/webgl-mochitest/ensure-exts/test_WEBGL_compressed_texture_es3.html
js/src/jsapi.h
services/sync/tests/unit/test_bookmark_livemarks.js
toolkit/components/places/tests/chrome/test_303567.xul
toolkit/components/places/tests/chrome/test_341972a.xul
toolkit/components/places/tests/chrome/test_341972b.xul
toolkit/components/places/tests/chrome/test_342484.xul
toolkit/components/places/tests/chrome/test_381357.xul
toolkit/components/places/tests/chrome/test_reloadLivemarks.xul
toolkit/components/places/tests/sync/livemark.xml
toolkit/components/places/tests/unit/livemark.xml
--- a/.cron.yml
+++ b/.cron.yml
@@ -73,28 +73,16 @@ jobs:
           treeherder-symbol: Vg
           target-tasks-method: mochitest_valgrind
       run-on-projects:
           - mozilla-central
       when:
           - {hour: 16, minute: 0}
           - {hour: 4, minute: 0}
 
-    - name: nightly-dmd
-      job:
-          type: decision-task
-          treeherder-symbol: Ndmd
-          target-tasks-method: nightly_dmd
-      run-on-projects:
-          - mozilla-central
-      when:
-          by-project:
-              mozilla-central: [{hour: 10, minute: 0}]
-              # No default
-
     - name: searchfox-index
       job:
           type: decision-task
           treeherder-symbol: Searchfox
           target-tasks-method: searchfox_index
       run-on-projects:
           - mozilla-central
       when:
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -503,43 +503,16 @@ var PlacesCommandHook = {
       bookmarkDialogInfo.title = URIList[0].title;
       bookmarkDialogInfo.uri = URIList[0].uri;
     }
 
     PlacesUIUtils.showBookmarkDialog(bookmarkDialogInfo, window);
   },
 
   /**
-   * Adds a Live Bookmark to a feed associated with the current page.
-   * @param     url
-   *            The nsIURI of the page the feed was attached to
-   * @title     title
-   *            The title of the feed. Optional.
-   */
-  async addLiveBookmark(url, feedTitle) {
-    let toolbarIP = new PlacesInsertionPoint({
-      parentId: PlacesUtils.toolbarFolderId,
-      parentGuid: PlacesUtils.bookmarks.toolbarGuid,
-    });
-
-    let feedURI = makeURI(url);
-    let title = feedTitle || gBrowser.contentTitle;
-
-    PlacesUIUtils.showBookmarkDialog({ action: "add",
-                                       type: "livemark",
-                                       feedURI,
-                                       siteURI: gBrowser.currentURI,
-                                       title,
-                                       defaultInsertionPoint: toolbarIP,
-                                       hiddenRows: [ "feedLocation",
-                                                     "siteLocation" ],
-                                     }, window);
-  },
-
-  /**
    * Opens the Places Organizer.
    * @param {String} item The item to select in the organizer window,
    *                      options are (case sensitive):
    *                      BookmarksMenu, BookmarksToolbar, UnfiledBookmarks,
    *                      AllBookmarks, History, Downloads.
    */
   showPlacesOrganizer(item) {
     var organizer = Services.wm.getMostRecentWindow("Places:Organizer");
--- a/browser/base/content/test/performance/browser_preferences_usage.js
+++ b/browser/base/content/test/performance/browser_preferences_usage.js
@@ -1,11 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
+const DEFAULT_PROCESS_COUNT = Services.prefs.getDefaultBranch(null).getIntPref("dom.ipc.processCount");
+
 /**
  * A test that checks whether any preference getter from the given list
  * of stats was called more often than the max parameter.
  *
  * @param {Array}  stats - an array of [prefName, accessCount] tuples
  * @param {Number} max - the maximum number of times any of the prefs should
  *                 have been called.
  * @param {Object} whitelist (optional) - an object that defines
@@ -115,17 +117,20 @@ add_task(async function startup() {
 
   ok(startupRecorder.data.prefStats, "startupRecorder has prefStats");
 
   checkPrefGetters(startupRecorder.data.prefStats, max, whitelist);
 });
 
 // This opens 10 tabs and checks pref getters.
 add_task(async function open_10_tabs() {
-  let max = 15;
+  // This is somewhat arbitrary. When we had a default of 4 content processes
+  // the value was 15. We need to scale it as we increase the number of
+  // content processes so we approximate with 4 * process_count.
+  const max = 4 * DEFAULT_PROCESS_COUNT;
 
   let whitelist = {
     "layout.css.dpi": {
       max: 35,
     },
     "browser.zoom.full": {
       min: 10,
       max: 25,
@@ -141,20 +146,16 @@ add_task(async function open_10_tabs() {
     "security.insecure_connection_text.enabled": {
       min: 10,
       max: 18,
     },
     "security.insecure_connection_text.pbmode.enabled": {
       min: 10,
       max: 18,
     },
-    "dom.ipc.processCount": {
-      min: 10,
-      max: 15,
-    },
     "browser.startup.record": {
       max: 20,
     },
     "browser.tabs.remote.logSwitchTiming": {
       max: 25,
     },
     "network.loadinfo.skip_type_assertion": {
       // This is accessed in debug only.
--- a/browser/components/extensions/test/browser/browser_ext_slow_script.js
+++ b/browser/components/extensions/test/browser/browser_ext_slow_script.js
@@ -1,26 +1,28 @@
 /* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set sts=2 sw=2 et tw=80: */
 "use strict";
 
+const DEFAULT_PROCESS_COUNT = Services.prefs.getDefaultBranch(null).getIntPref("dom.ipc.processCount");
+
 add_task(async function test_slow_content_script() {
   // Make sure we get a new process for our tab, or our reportProcessHangs
   // preferences value won't apply to it.
   await SpecialPowers.pushPrefEnv({
     set: [
       ["dom.ipc.processCount", 1],
       ["dom.ipc.keepProcessesAlive.web", 0],
     ],
   });
   await SpecialPowers.popPrefEnv();
 
   await SpecialPowers.pushPrefEnv({
     set: [
-      ["dom.ipc.processCount", 8],
+      ["dom.ipc.processCount", DEFAULT_PROCESS_COUNT * 2],
       ["dom.ipc.processPrelaunch.enabled", false],
       ["dom.ipc.reportProcessHangs", true],
     ],
   });
 
   let extension = ExtensionTestUtils.loadExtension({
     useAddonManager: "temporary",
 
--- a/browser/components/extensions/test/browser/head.js
+++ b/browser/components/extensions/test/browser/head.js
@@ -38,16 +38,21 @@ const {AppConstants} = ChromeUtils.impor
 const {CustomizableUI} = ChromeUtils.import("resource:///modules/CustomizableUI.jsm", {});
 const {Preferences} = ChromeUtils.import("resource://gre/modules/Preferences.jsm", {});
 
 XPCOMUtils.defineLazyGetter(this, "Management", () => {
   const {Management} = ChromeUtils.import("resource://gre/modules/Extension.jsm", {});
   return Management;
 });
 
+// The extension tests can run a lot slower under ASAN.
+if (AppConstants.ASAN) {
+  SimpleTest.requestLongerTimeout(10);
+}
+
 // We run tests under two different configurations, from browser.ini and
 // browser-remote.ini. When running from browser-remote.ini, the tests are
 // copied to the sub-directory "test-oop-extensions", which we detect here, and
 // use to select our configuration.
 let remote = gTestPath.includes("test-oop-extensions");
 SpecialPowers.pushPrefEnv({set: [
   ["extensions.webextensions.remote", remote],
 ]});
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -397,16 +397,17 @@ XPCOMUtils.defineLazyModuleGetters(this,
   FormValidationHandler: "resource:///modules/FormValidationHandler.jsm",
   FxAccounts: "resource://gre/modules/FxAccounts.jsm",
   HomePage: "resource:///modules/HomePage.jsm",
   HybridContentTelemetry: "resource://gre/modules/HybridContentTelemetry.jsm",
   Integration: "resource://gre/modules/Integration.jsm",
   L10nRegistry: "resource://gre/modules/L10nRegistry.jsm",
   LanguagePrompt: "resource://gre/modules/LanguagePrompt.jsm",
   LightweightThemeManager: "resource://gre/modules/LightweightThemeManager.jsm",
+  LiveBookmarkMigrator: "resource:///modules/LiveBookmarkMigrator.jsm",
   LoginHelper: "resource://gre/modules/LoginHelper.jsm",
   LoginManagerParent: "resource://gre/modules/LoginManagerParent.jsm",
   NewTabUtils: "resource://gre/modules/NewTabUtils.jsm",
   Normandy: "resource://normandy/Normandy.jsm",
   ObjectUtils: "resource://gre/modules/ObjectUtils.jsm",
   OS: "resource://gre/modules/osfile.jsm",
   PageActions: "resource:///modules/PageActions.jsm",
   PageThumbs: "resource://gre/modules/PageThumbs.jsm",
@@ -1575,16 +1576,22 @@ BrowserGlue.prototype = {
 
     Services.tm.idleDispatchToMainThread(() => {
       LanguagePrompt.init();
     });
 
     Services.tm.idleDispatchToMainThread(() => {
       Blocklist.loadBlocklistAsync();
     });
+
+    if (Services.prefs.getIntPref("browser.livebookmarks.migrationAttemptsLeft", 0) > 0) {
+      Services.tm.idleDispatchToMainThread(() => {
+        LiveBookmarkMigrator.migrate().catch(Cu.reportError);
+      });
+    }
   },
 
   /**
    * Use this function as an entry point to schedule tasks that need
    * to run once per session, at any arbitrary point in time.
    * This function will be called from an idle observer. Check the value of
    * LATE_TASKS_IDLE_TIME_SEC to see the current value for this idle
    * observer.
@@ -2119,17 +2126,17 @@ BrowserGlue.prototype = {
       }
     }
   },
 
   // eslint-disable-next-line complexity
   _migrateUI: function BG__migrateUI() {
     // Use an increasing number to keep track of the current migration state.
     // Completely unrelated to the current Firefox release number.
-    const UI_VERSION = 73;
+    const UI_VERSION = 74;
     const BROWSER_DOCURL = AppConstants.BROWSER_CHROME_URL;
 
     let currentUIVersion;
     if (Services.prefs.prefHasUserValue("browser.migration.version")) {
       currentUIVersion = Services.prefs.getIntPref("browser.migration.version");
     } else {
       // This is a new profile, nothing to migrate.
       Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
@@ -2466,16 +2473,23 @@ BrowserGlue.prototype = {
                         { ignoreAbsent: true });
       for (const filename of ["addons.json", "plugins.json", "gfx.json"]) {
         // Some old versions used to dump without subfolders. Clean them while we are at it.
         const path = OS.Path.join(OS.Constants.Path.profileDir, `blocklists-${filename}`);
         OS.File.remove(path, { ignoreAbsent: true });
       }
     }
 
+    if (currentUIVersion < 74) {
+      // Ensure we try to migrate any live bookmarks the user might have, trying up to
+      // 5 times. We set this early, and here, to avoid running the migration on
+      // new profile (or, indeed, ever creating the pref there).
+      Services.prefs.setIntPref("browser.livebookmarks.migrationAttemptsLeft", 5);
+    }
+
     // Update the migration version.
     Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
   },
 
   _checkForDefaultBrowser() {
     // Perform default browser checking.
     if (!ShellService) {
       return;
--- a/browser/components/places/content/bookmarkProperties.js
+++ b/browser/components/places/content/bookmarkProperties.js
@@ -8,39 +8,38 @@
  * as window.arguments[0]. The object must have the following fields set:
  *   @ action (String). Possible values:
  *     - "add" - for adding a new item.
  *       @ type (String). Possible values:
  *         - "bookmark"
  *         - "folder"
  *           @ URIList (Array of nsIURI objects) - optional, list of uris to
  *             be bookmarked under the new folder.
- *         - "livemark"
  *       @ uri (nsIURI object) - optional, the default uri for the new item.
  *         The property is not used for the "folder with items" type.
  *       @ title (String) - optional, the default title for the new item.
  *       @ defaultInsertionPoint (InsertionPoint JS object) - optional, the
  *         default insertion point for the new item.
  *       @ keyword (String) - optional, the default keyword for the new item.
  *       @ postData (String) - optional, POST data to accompany the keyword.
  *       @ charSet (String) - optional, character-set to accompany the keyword.
  *      Notes:
- *        1) If |uri| is set for a bookmark/livemark item and |title| isn't,
+ *        1) If |uri| is set for a bookmark and |title| isn't,
  *           the dialog will query the history tables for the title associated
  *           with the given uri. If the dialog is set to adding a folder with
  *           bookmark items under it (see URIList), a default static title is
  *           used ("[Folder Name]").
  *        2) The index field of the default insertion point is ignored if
  *           the folder picker is shown.
  *     - "edit" - for editing a bookmark item or a folder.
  *       @ type (String). Possible values:
  *         - "bookmark"
  *           @ node (an nsINavHistoryResultNode object) - a node representing
  *             the bookmark.
- *         - "folder" (also applies to livemarks)
+ *         - "folder"
  *           @ node (an nsINavHistoryResultNode object) - a node representing
  *             the folder.
  *   @ hiddenRows (Strings array) - optional, list of rows to be hidden
  *     regardless of the item edited or added by the dialog.
  *     Possible values:
  *     - "title"
  *     - "location"
  *     - "keyword"
@@ -67,17 +66,16 @@ XPCOMUtils.defineLazyScriptGetter(this, 
                                   "chrome://browser/content/places/treeView.js");
 XPCOMUtils.defineLazyScriptGetter(this, ["PlacesInsertionPoint", "PlacesController",
                                          "PlacesControllerDragHelper"],
                                   "chrome://browser/content/places/controller.js");
 /* End Shared Places Import */
 
 const BOOKMARK_ITEM = 0;
 const BOOKMARK_FOLDER = 1;
-const LIVEMARK_CONTAINER = 2;
 
 const ACTION_EDIT = 0;
 const ACTION_ADD = 1;
 
 var elementsHeight = new Map();
 
 var BookmarkPropertiesPanel = {
 
@@ -108,37 +106,32 @@ var BookmarkPropertiesPanel = {
    * This method returns the correct label for the dialog's "accept"
    * button based on the variant of the dialog.
    */
   _getAcceptLabel: function BPP__getAcceptLabel() {
     if (this._action == ACTION_ADD) {
       if (this._URIs.length)
         return this._strings.getString("dialogAcceptLabelAddMulti");
 
-      if (this._itemType == LIVEMARK_CONTAINER)
-        return this._strings.getString("dialogAcceptLabelAddLivemark");
-
       if (this._dummyItem)
         return this._strings.getString("dialogAcceptLabelAddItem");
 
       return this._strings.getString("dialogAcceptLabelSaveItem");
     }
     return this._strings.getString("dialogAcceptLabelEdit");
   },
 
   /**
    * This method returns the correct title for the current variant
    * of this dialog.
    */
   _getDialogTitle: function BPP__getDialogTitle() {
     if (this._action == ACTION_ADD) {
       if (this._itemType == BOOKMARK_ITEM)
         return this._strings.getString("dialogTitleAddBookmark");
-      if (this._itemType == LIVEMARK_CONTAINER)
-        return this._strings.getString("dialogTitleAddLivemark");
 
       // add folder
       if (this._itemType != BOOKMARK_FOLDER)
         throw new Error("Unknown item type");
       if (this._URIs.length)
         return this._strings.getString("dialogTitleAddMulti");
 
       return this._strings.getString("dialogTitleAddFolder");
@@ -206,31 +199,16 @@ var BookmarkPropertiesPanel = {
             if ("URIList" in dialogInfo) {
               this._title = this._strings.getString("bookmarkAllTabsDefault");
               this._URIs = dialogInfo.URIList;
             } else
               this._title = this._strings.getString("newFolderDefault");
               this._dummyItem = true;
           }
           break;
-
-        case "livemark":
-          this._itemType = LIVEMARK_CONTAINER;
-          if ("feedURI" in dialogInfo)
-            this._feedURI = dialogInfo.feedURI;
-          if ("siteURI" in dialogInfo)
-            this._siteURI = dialogInfo.siteURI;
-
-          if (!this._title) {
-            if (this._feedURI) {
-              this._title = await PlacesUtils.history.fetch(this._feedURI) ||
-                            this._feedURI.spec;
-            } else
-              this._title = this._strings.getString("newLivemarkDefault");
-          }
       }
     } else { // edit
       this._node = dialogInfo.node;
       this._title = this._node.title;
       if (PlacesUtils.nodeIsFolder(this._node))
         this._itemType = BOOKMARK_FOLDER;
       else if (PlacesUtils.nodeIsURI(this._node))
         this._itemType = BOOKMARK_ITEM;
@@ -468,22 +446,16 @@ var BookmarkPropertiesPanel = {
       if (this._postData)
         info.postData = this._postData;
 
       if (this._charSet) {
         PlacesUIUtils.setCharsetForPage(this._uri, this._charSet, window).catch(Cu.reportError);
       }
 
       itemGuid = await PlacesTransactions.NewBookmark(info).transact();
-    } else if (this._itemType == LIVEMARK_CONTAINER) {
-      info.feedUrl = this._feedURI;
-      if (this._siteURI)
-        info.siteUrl = this._siteURI;
-
-      itemGuid = await PlacesTransactions.NewLivemark(info).transact();
     } else if (this._itemType == BOOKMARK_FOLDER) {
       // NewFolder requires a url rather than uri.
       info.children = this._URIs.map(item => {
         return { url: item.uri, title: item.title };
       });
       itemGuid = await PlacesTransactions.NewFolder(info).transact();
     } else {
       throw new Error(`unexpected value for _itemType:  ${this._itemType}`);
--- a/browser/components/places/content/controller.js
+++ b/browser/components/places/content/controller.js
@@ -682,17 +682,17 @@ PlacesController.prototype = {
     else
       PlacesUIUtils.openURINodesInTabs(nodes, aEvent, this._view);
   },
 
   /**
    * Shows the Add Bookmark UI for the current insertion point.
    *
    * @param aType
-   *        the type of the new item (bookmark/livemark/folder)
+   *        the type of the new item (bookmark/folder)
    */
   async newItem(aType) {
     let ip = this._view.insertionPoint;
     if (!ip)
       throw Cr.NS_ERROR_NOT_AVAILABLE;
 
     let bookmarkGuid =
       PlacesUIUtils.showBookmarkDialog({ action: "add",
--- a/browser/components/places/tests/browser/browser.ini
+++ b/browser/components/places/tests/browser/browser.ini
@@ -27,18 +27,16 @@ support-files =
 skip-if = os != 'mac' # Mac-only functionality
 [browser_bookmarks_change_title.js]
 [browser_bookmarks_sidebar_search.js]
 support-files =
   pageopeningwindow.html
 [browser_bookmarkProperties_addFolderDefaultButton.js]
 [browser_bookmarkProperties_addKeywordForThisSearch.js]
 skip-if = (verify && debug)
-[browser_bookmarkProperties_addLivemark.js]
-skip-if = (verify && debug && (os == 'linux' || os == 'win'))
 [browser_bookmarkProperties_bookmarkAllTabs.js]
 skip-if = (verify && debug && (os == 'win' || os == 'mac'))
 [browser_bookmarkProperties_cancel.js]
 [browser_bookmarkProperties_editFolder.js]
 [browser_bookmarkProperties_editTagContainer.js]
 [browser_bookmarkProperties_no_user_actions.js]
 [browser_bookmarkProperties_newFolder.js]
 [browser_bookmarkProperties_readOnlyRoot.js]
deleted file mode 100644
--- a/browser/components/places/tests/browser/browser_bookmarkProperties_addLivemark.js
+++ /dev/null
@@ -1,38 +0,0 @@
-"use strict";
-
-add_task(async function() {
-  info("Add a live bookmark editing its data");
-
-  await withSidebarTree("bookmarks", async function(tree) {
-    tree.selectItems([PlacesUtils.bookmarks.unfiledGuid]);
-
-    await withBookmarksDialog(
-      true,
-      function openDialog() {
-        PlacesCommandHook.addLiveBookmark("http://livemark.com/",
-                                          "livemark", "description");
-      },
-      async function test(dialogWin) {
-        let promiseTitleChangeNotification = PlacesTestUtils.waitForNotification(
-          "onItemChanged", (unused, prop, isAnno, val) => prop == "title" && val == "modified");
-
-        fillBookmarkTextField("editBMPanel_namePicker", "modified", dialogWin);
-
-        await promiseTitleChangeNotification;
-
-        let bookmark = await PlacesUtils.bookmarks.fetch({
-          parentGuid: PlacesUtils.bookmarks.toolbarGuid,
-          index: PlacesUtils.bookmarks.DEFAULT_INDEX,
-        });
-
-        Assert.equal(bookmark.title, "modified", "folder name has been edited");
-
-        let livemark = await PlacesUtils.livemarks.getLivemark({
-          guid: bookmark.guid,
-        });
-        Assert.equal(livemark.feedURI.spec, "http://livemark.com/", "livemark has the correct url");
-        Assert.equal(livemark.title, "modified", "livemark has the correct title");
-      }
-    );
-  });
-});
--- a/browser/components/preferences/in-content/main.xul
+++ b/browser/components/preferences/in-content/main.xul
@@ -608,16 +608,17 @@
         <menupopup>
           <menuitem label="1" value="1"/>
           <menuitem label="2" value="2"/>
           <menuitem label="3" value="3"/>
           <menuitem label="4" value="4"/>
           <menuitem label="5" value="5"/>
           <menuitem label="6" value="6"/>
           <menuitem label="7" value="7"/>
+          <menuitem label="8" value="8"/>
         </menupopup>
       </menulist>
     </hbox>
     <description id="contentProcessCountEnabledDescription" class="tip-caption" data-l10n-id="performance-limit-content-process-enabled-desc"/>
     <description id="contentProcessCountDisabledDescription" class="tip-caption" data-l10n-id="performance-limit-content-process-blocked-desc">
       <html:a class="text-link" data-l10n-name="learn-more" href="https://wiki.mozilla.org/Electrolysis"/>
     </description>
   </vbox>
--- a/browser/components/preferences/in-content/tests/browser_performance_e10srollout.js
+++ b/browser/components/preferences/in-content/tests/browser_performance_e10srollout.js
@@ -39,30 +39,32 @@ add_task(async function testPrefsAreDefa
 
   BrowserTestUtils.removeTab(gBrowser.selectedTab);
 
   Services.prefs.clearUserPref("dom.ipc.processCount");
   Services.prefs.setBoolPref("browser.preferences.defaultPerformanceSettings.enabled", true);
 });
 
 add_task(async function testPrefsSetByUser() {
-  Services.prefs.setIntPref("dom.ipc.processCount", DEFAULT_PROCESS_COUNT + 2);
+  const kNewCount = DEFAULT_PROCESS_COUNT - 2;
+
+  Services.prefs.setIntPref("dom.ipc.processCount", kNewCount);
   Services.prefs.setBoolPref("browser.preferences.defaultPerformanceSettings.enabled", false);
 
   let prefs = await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
   is(prefs.selectedPane, "paneGeneral", "General pane was selected");
 
   let doc = gBrowser.contentDocument;
   let performanceSettings = doc.querySelector("#performanceSettings");
   is(performanceSettings.hidden, false, "performance settings section is shown");
 
   let contentProcessCount = doc.querySelector("#contentProcessCount");
   is(contentProcessCount.disabled, false, "process count control should be enabled");
-  is(Services.prefs.getIntPref("dom.ipc.processCount"), DEFAULT_PROCESS_COUNT + 2, "process count should be the set value");
-  is(contentProcessCount.selectedItem.value, DEFAULT_PROCESS_COUNT + 2, "selected item should be the set one");
+  is(Services.prefs.getIntPref("dom.ipc.processCount"), kNewCount, "process count should be the set value");
+  is(contentProcessCount.selectedItem.value, kNewCount, "selected item should be the set one");
 
   let useRecommendedPerformanceSettings = doc.querySelector("#useRecommendedPerformanceSettings");
   useRecommendedPerformanceSettings.click();
 
   is(Services.prefs.getBoolPref("browser.preferences.defaultPerformanceSettings.enabled"), true,
     "pref value should be true after clicking on checkbox");
   is(Services.prefs.getIntPref("dom.ipc.processCount"), DEFAULT_PROCESS_COUNT,
     "process count should be default value");
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -978,8 +978,13 @@ autoplay.messageWithFile = Will you allo
 # popup panels, including the sliding subviews of the main menu.
 panel.back = Back
 
 confirmationHint.sendToDevice.label = Sent!
 confirmationHint.sendToDeviceOffline.label = Queued (offline)
 confirmationHint.copyURL.label = Copied to clipboard!
 confirmationHint.pageBookmarked.label = Saved to Library!
 confirmationHint.addSearchEngine.label = Search engine added!
+
+# LOCALIZATION NOTE (livebookmarkMigration.title):
+# Used by the export of user's live bookmarks to an OPML file as a title for the file.
+# %S will be replaced with brandShortName
+livebookmarkMigration.title                      = %S Live Bookmarks
--- a/browser/locales/en-US/chrome/browser/places/bookmarkProperties.properties
+++ b/browser/locales/en-US/chrome/browser/places/bookmarkProperties.properties
@@ -1,19 +1,16 @@
 # 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/.
 
 dialogAcceptLabelAddItem=Add
 dialogAcceptLabelSaveItem=Save
-dialogAcceptLabelAddLivemark=Subscribe
 dialogAcceptLabelAddMulti=Add Bookmarks
 dialogAcceptLabelEdit=Save
 dialogTitleAddBookmark=New Bookmark
-dialogTitleAddLivemark=Subscribe with Live Bookmark
 dialogTitleAddFolder=New Folder
 dialogTitleAddMulti=New Bookmarks
 dialogTitleEdit=Properties for “%S”
 
 bookmarkAllTabsDefault=[Folder Name]
 newFolderDefault=New Folder
 newBookmarkDefault=New Bookmark
-newLivemarkDefault=New Live Bookmark
new file mode 100644
--- /dev/null
+++ b/browser/modules/LiveBookmarkMigrator.jsm
@@ -0,0 +1,229 @@
+/* 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/. */
+
+"use strict";
+
+ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
+ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+XPCOMUtils.defineLazyModuleGetters(this, {
+  BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm",
+  OS: "resource://gre/modules/osfile.jsm",
+  PlacesUtils: "resource://gre/modules/PlacesUtils.jsm",
+});
+
+XPCOMUtils.defineLazyGlobalGetters(this, ["URL", "XMLSerializer"]);
+
+XPCOMUtils.defineLazyGetter(this, "gBrowserBundle", function() {
+  return Services.strings.createBundle("chrome://browser/locale/browser.properties");
+});
+
+const kMigrationPref = "browser.livebookmarks.migrationAttemptsLeft";
+
+function migrationSucceeded() {
+  Services.prefs.clearUserPref(kMigrationPref);
+}
+
+function migrationError() {
+  // Decrement the number of remaining attempts.
+  let remainingAttempts = Math.max(0, Services.prefs.getIntPref(kMigrationPref, 1) - 1);
+  Services.prefs.setIntPref(kMigrationPref, remainingAttempts);
+}
+
+var LiveBookmarkMigrator = {
+  _isOldDefaultBookmark(liveBookmark) {
+    if (!liveBookmark.feedURI || !liveBookmark.feedURI.host) {
+      return false;
+    }
+    let {host} = liveBookmark.feedURI;
+    return host.endsWith("fxfeeds.mozilla.com") || host.endsWith("fxfeeds.mozilla.org");
+  },
+
+  async _fetch() {
+    function getAnnoSQLFragment(aAnnoParam) {
+      return `SELECT a.content
+              FROM moz_items_annos a
+              JOIN moz_anno_attributes n ON n.id = a.anno_attribute_id
+              WHERE a.item_id = b.id
+                AND n.name = ${aAnnoParam}`;
+    }
+
+    // Copied and modified from nsLivemarkService.js, which we'll want to remove even when
+    // we keep this migration for a while.
+    const LB_SQL =
+      `SELECT b.title, b.guid, b.dateAdded, b.position as 'index', p.guid AS parentGuid,
+              ( ${getAnnoSQLFragment(":feedURI_anno")} ) AS feedURI,
+              ( ${getAnnoSQLFragment(":siteURI_anno")} ) AS siteURI
+            FROM moz_bookmarks b
+            JOIN moz_bookmarks p ON b.parent = p.id
+            JOIN moz_items_annos a ON a.item_id = b.id
+            JOIN moz_anno_attributes n ON a.anno_attribute_id = n.id
+            WHERE b.type = :folder_type
+              AND n.name = :feedURI_anno
+      ORDER BY b.position DESC`;
+    // We sort by position so we go over items last-to-first. This way, we can insert a
+    // duplicate "normal" bookmark for each livemark, without causing future insertions
+    // to be off-by-N in their positioning because of the insertions.
+
+    let conn = await PlacesUtils.promiseDBConnection();
+    let rows = await conn.execute(LB_SQL,
+      { folder_type: Ci.nsINavBookmarksService.TYPE_FOLDER,
+        feedURI_anno: PlacesUtils.LMANNO_FEEDURI,
+        siteURI_anno: PlacesUtils.LMANNO_SITEURI });
+    // Create a JS object out of the sqlite result:
+    let liveBookmarks = [];
+    for (let row of rows) {
+      let siteURI = row.getResultByName("siteURI");
+      let feedURI = row.getResultByName("feedURI");
+      try {
+        feedURI = new URL(feedURI);
+        siteURI = siteURI ? new URL(siteURI) : null;
+      } catch (ex) {
+        // Skip items with broken URLs:
+        Cu.reportError(ex);
+        continue;
+      }
+      liveBookmarks.push({
+        guid: row.getResultByName("guid"),
+        index: row.getResultByName("index"),
+        dateAdded: PlacesUtils.toDate(row.getResultByName("dateAdded")),
+        parentGuid: row.getResultByName("parentGuid"),
+        title: row.getResultByName("title"),
+        siteURI,
+        feedURI,
+      });
+    }
+    return liveBookmarks;
+  },
+
+  async _writeOPML(liveBookmarks) {
+    const appName = Services.appinfo.name;
+    let hiddenBrowser = Services.appShell.createWindowlessBrowser();
+    let opmlString = "";
+    try {
+      let hiddenDOMDoc = hiddenBrowser.document;
+      // Create head:
+      let doc = hiddenDOMDoc.implementation.createDocument("", "opml", null);
+      let root = doc.documentElement;
+      root.setAttribute("version", "1.0");
+      let head = doc.createElement("head");
+      root.appendChild(head);
+      let title = doc.createElement("title");
+      title.textContent =
+        gBrowserBundle.formatStringFromName("livebookmarkMigration.title", [appName], 1);
+      head.appendChild(title);
+
+      let body = doc.createElement("body");
+      root.appendChild(body);
+      // Make things vaguely readable:
+      body.textContent = "\n";
+
+      for (let lb of liveBookmarks) {
+        if (this._isOldDefaultBookmark(lb)) {
+          // Ignore the old default bookmarks and don't back them up.
+          continue;
+        }
+        let outline = doc.createElement("outline");
+        outline.setAttribute("type", "rss");
+        outline.setAttribute("title", lb.title);
+        outline.setAttribute("text", lb.title);
+        outline.setAttribute("xmlUrl", lb.feedURI.href);
+        if (lb.siteURI) {
+          outline.setAttribute("htmlUrl", lb.siteURI.href);
+        }
+        body.appendChild(outline);
+        body.appendChild(doc.createTextNode("\n"));
+      }
+
+      let serializer = new XMLSerializer();
+      // The serializer doesn't add an XML declaration (bug 318086), so we add it manually.
+      opmlString = '<?xml version="1.0"?>\n' + serializer.serializeToString(doc);
+    } finally {
+      hiddenBrowser.close();
+    }
+
+    let {path: basePath} = Services.dirsvc.get("Desk", Ci.nsIFile);
+    let feedFileName = appName + " feeds backup.opml";
+    basePath = OS.Path.join(basePath, feedFileName);
+    let {file, path} = await OS.File.openUnique(basePath, {humanReadable: true});
+    await file.close();
+    return OS.File.writeAtomic(path, opmlString, {encoding: "utf-8"});
+  },
+
+  async _transformBookmarks(liveBookmarks) {
+    let itemsToReplace = liveBookmarks.filter(lb => !this._isOldDefaultBookmark(lb));
+    let itemsToInsert = itemsToReplace.map(item => ({
+      url: item.siteURI || item.feedURI,
+      parentGuid: item.parentGuid,
+      index: item.index,
+      title: item.title,
+      dateAdded: item.dateAdded,
+    }));
+    // Insert new bookmarks at the same index. The list is sorted by position
+    // in reverse order, so we'll insert later items before the earlier ones.
+    // This avoids the indices getting outdated for later insertions.
+    for (let item of itemsToInsert) {
+      await PlacesUtils.bookmarks.insert(item).catch(Cu.reportError);
+    }
+    // Now remove all of the actual live bookmarks. Avoid mismatches due to the
+    // bookmarks having been moved or altered in the meantime, just remove
+    // anything with a matching guid:
+    let itemsToRemove = liveBookmarks.map(lb => ({guid: lb.guid}));
+    await PlacesUtils.bookmarks.remove(itemsToRemove).catch(Cu.reportError);
+  },
+
+  _openSUMOPage() {
+    let sumoURL = Services.urlFormatter.formatURLPref("app.support.baseURL") + "live-bookmarks-migration";
+    let topWin = BrowserWindowTracker.getTopWindow({private: false});
+    if (!topWin) {
+      let args = PlacesUtils.toISupportsString(sumoURL);
+      Services.ww.openWindow(null, AppConstants.BROWSER_CHROME_URL, "_blank", "chrome,dialog=no,all", args);
+    } else {
+      topWin.openTrustedLinkIn(sumoURL, "tab");
+    }
+  },
+
+  async migrate() {
+    try {
+      // First fetch all live bookmark folders:
+      let liveBookmarks = await this._fetch();
+      if (!liveBookmarks || !liveBookmarks.length) {
+        migrationSucceeded();
+        return;
+      }
+
+      let haveNonDefaultBookmarks = liveBookmarks.some(lb => !this._isOldDefaultBookmark(lb));
+      // Then generate OPML file content, write to disk, if we've got anything to back up:
+      if (haveNonDefaultBookmarks) {
+        await this._writeOPML(liveBookmarks);
+      }
+      // Replace all live bookmarks with normal bookmarks.
+      await this._transformBookmarks(liveBookmarks).catch(ex => {
+        // Don't stop migrating at this point, because we've written the exported OPML file.
+        // We shouldn't ever hit this - transformLiveBookmarks is supposed to take
+        // care of its own failures.
+        Cu.reportError(ex);
+      });
+
+      try {
+        if (haveNonDefaultBookmarks) {
+          this._openSUMOPage();
+        }
+      } catch (ex) {
+        // Note that if we get here, we've removed any extant livemarks, so there's no point
+        // re-running the migration - there won't be any livemarks left and we won't re-show the SUMO
+        // page. So just report the error, but mark migration as successful.
+        Cu.reportError(new Error("Live bookmarks migration didn't manage to show the support page: " + ex));
+      }
+    } catch (ex) {
+      migrationError();
+      throw ex;
+    }
+
+    migrationSucceeded();
+  },
+};
+
+var EXPORTED_SYMBOLS = ["LiveBookmarkMigrator"];
--- a/browser/modules/moz.build
+++ b/browser/modules/moz.build
@@ -59,16 +59,19 @@ with Files("ContentSearch.jsm"):
     BUG_COMPONENT = ("Firefox", "Search")
 
 with Files("ExtensionsUI.jsm"):
     BUG_COMPONENT = ("WebExtensions", "General")
 
 with Files("LaterRun.jsm"):
     BUG_COMPONENT = ("Firefox", "Tours")
 
+with Files("LiveBookmarkMigrator.jsm"):
+    BUG_COMPONENT = ("Firefox", "RSS Discovery and Preview")
+
 with Files("OpenInTabsUtils.jsm"):
     BUG_COMPONENT = ("Firefox", "Tabbed Browser")
 
 with Files("PermissionUI.jsm"):
    BUG_COMPONENT = ("Firefox", "Site Identity and Permission Panels")
 
 with Files("ProcessHangMonitor.jsm"):
     BUG_COMPONENT = ("Core", "DOM: Content Processes")
@@ -128,16 +131,17 @@ EXTRA_JS_MODULES += [
     'ContentObservers.js',
     'ContentSearch.jsm',
     'ExtensionsUI.jsm',
     'FaviconLoader.jsm',
     'Feeds.jsm',
     'FormValidationHandler.jsm',
     'HomePage.jsm',
     'LaterRun.jsm',
+    'LiveBookmarkMigrator.jsm',
     'OpenInTabsUtils.jsm',
     'PageActions.jsm',
     'PermissionUI.jsm',
     'PingCentre.jsm',
     'ProcessHangMonitor.jsm',
     'ReaderParent.jsm',
     'RemotePrompt.jsm',
     'Sanitizer.jsm',
--- a/browser/modules/test/browser/browser.ini
+++ b/browser/modules/test/browser/browser.ini
@@ -15,16 +15,17 @@ support-files =
 [browser_ContentSearch.js]
 support-files =
   contentSearch.js
   contentSearchBadImage.xml
   contentSearchSuggestions.sjs
   contentSearchSuggestions.xml
   !/browser/components/search/test/head.js
   !/browser/components/search/test/testEngine.xml
+[browser_LiveBookmarkMigrator.js]
 [browser_PageActions.js]
 [browser_PermissionUI.js]
 [browser_PermissionUI_prompts.js]
 [browser_ProcessHangNotifications.js]
 skip-if = !e10s
 [browser_SitePermissions.js]
 [browser_SitePermissions_combinations.js]
 [browser_SitePermissions_expiry.js]
new file mode 100644
--- /dev/null
+++ b/browser/modules/test/browser/browser_LiveBookmarkMigrator.js
@@ -0,0 +1,20 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+"use strict";
+
+// Check migrator can open the SUMO page.
+add_task(async function() {
+  let expectedURL = Services.prefs.getCharPref("app.support.baseURL") +
+    "live-bookmarks-migration";
+  let newTabExpected = BrowserTestUtils.waitForNewTab(gBrowser, expectedURL, true);
+  let {LiveBookmarkMigrator} = ChromeUtils.import("resource:///modules/LiveBookmarkMigrator.jsm", {});
+  LiveBookmarkMigrator._openSUMOPage();
+  await newTabExpected;
+  // If we get here, this is guaranteed to pass, but otherwise mochitest complains that
+  // the test has no assertions.
+  is(gBrowser.selectedBrowser.currentURI.spec, expectedURL, "Should have opened the right page");
+  gBrowser.removeCurrentTab();
+});
+
new file mode 100644
--- /dev/null
+++ b/browser/modules/test/unit/test_LiveBookmarkMigrator.js
@@ -0,0 +1,167 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+/* globals ChromeUtils, Assert, add_task */
+"use strict";
+
+ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+// Ensure we initialize places:
+do_get_profile();
+
+ChromeUtils.defineModuleGetter(this, "PlacesUIUtils",
+                               "resource:///modules/PlacesUIUtils.jsm");
+
+// Needed because we rely on the app name for the OPML file name and title.
+ChromeUtils.import("resource://testing-common/AppInfo.jsm", this);
+updateAppInfo({
+  name: "LiveBookmarkMigratorTest",
+  ID: "{230de50e-4cd1-11dc-8314-0800200c9a66}",
+  version: "1",
+  platformVersion: "",
+});
+
+const {PlacesUtils} =
+  ChromeUtils.import("resource://gre/modules/PlacesUtils.jsm", {});
+const {LiveBookmarkMigrator} =
+  ChromeUtils.import("resource:///modules/LiveBookmarkMigrator.jsm", {});
+
+Cu.importGlobalProperties(["URL"]);
+
+const kTestData = {
+  guid: PlacesUtils.bookmarks.toolbarGuid,
+  children: [
+    {type: PlacesUtils.bookmarks.TYPE_BOOKMARK, title: "BM 1", url: new URL("https://example.com/1")},
+    {type: PlacesUtils.bookmarks.TYPE_FOLDER, title: "LB 1"},
+    {type: PlacesUtils.bookmarks.TYPE_BOOKMARK, title: "BM 2", url: new URL("https://example.com/2")},
+    {type: PlacesUtils.bookmarks.TYPE_FOLDER, title: "Regular old folder", children: [
+      {type: PlacesUtils.bookmarks.TYPE_FOLDER, title: "LB child 1"},
+      {type: PlacesUtils.bookmarks.TYPE_BOOKMARK, title: "BM child 1", url: new URL("https://example.com/1/1")},
+      {type: PlacesUtils.bookmarks.TYPE_FOLDER, title: "LB child 2"},
+      {type: PlacesUtils.bookmarks.TYPE_BOOKMARK, title: "BM child 2", url: new URL("https://example.com/1/2")},
+    ]},
+    {type: PlacesUtils.bookmarks.TYPE_FOLDER, title: "LB 2"},
+    {type: PlacesUtils.bookmarks.TYPE_BOOKMARK, title: "BM 3", url: new URL("https://example.com/3")},
+    {type: PlacesUtils.bookmarks.TYPE_FOLDER, title: "LB 3"},
+    // The next two will be skipped because we ignore the feeds we used to ship by default:
+    {type: PlacesUtils.bookmarks.TYPE_FOLDER, title: "Default live bookmark 4"},
+    {type: PlacesUtils.bookmarks.TYPE_FOLDER, title: "Default live bookmark 5"},
+  ],
+};
+
+const kDefaultFeedURLsToTest = ["http://en-US.fxfeeds.mozilla.com/", "http://fxfeeds.mozilla.org/"];
+
+registerCleanupFunction(async () => {
+  await PlacesUtils.bookmarks.eraseEverything();
+});
+
+add_task(async function setup() {
+  let insertedItems = await PlacesUtils.bookmarks.insertTree(kTestData);
+  for (let item of insertedItems) {
+    if (item.title.includes("LB")) {
+      let id = await PlacesUtils.promiseItemId(item.guid);
+      let feedID = item.title.replace(/[^0-9]/g, "");
+      PlacesUtils.annotations.setItemAnnotation(id, PlacesUtils.LMANNO_FEEDURI,
+                                "https://example.com/feed/" + feedID,
+                                0, PlacesUtils.annotations.EXPIRE_NEVER,
+                                PlacesUtils.bookmarks.SOURCES.DEFAULT, true);
+      // For half the feeds, set a site URI as well.
+      if (parseInt(feedID) % 2) {
+        PlacesUtils.annotations.setItemAnnotation(id, PlacesUtils.LMANNO_SITEURI,
+                                  "https://example.com/feedpage/" + feedID,
+                                  0, PlacesUtils.annotations.EXPIRE_NEVER,
+                                  PlacesUtils.bookmarks.SOURCES.DEFAULT, true);
+      }
+    } else if (item.title.includes("Default live bookmark")) {
+      let id = await PlacesUtils.promiseItemId(item.guid);
+      PlacesUtils.annotations.setItemAnnotation(id, PlacesUtils.LMANNO_FEEDURI,
+                                kDefaultFeedURLsToTest.pop(),
+                                0, PlacesUtils.annotations.EXPIRE_NEVER,
+                                PlacesUtils.bookmarks.SOURCES.DEFAULT, true);
+    }
+  }
+});
+
+// Test fetching LB with and without siteURIs works. Check ordering is last-positioned-first.
+add_task(async function check_fetches_livemarks_correctly() {
+  let detectedLiveBookmarks = await LiveBookmarkMigrator._fetch();
+  Assert.equal(detectedLiveBookmarks.length, 7, "Should have 7 live bookmarks");
+  Assert.notEqual(detectedLiveBookmarks.filter(lb => lb.siteURI).length, 0,
+                  "Should have more than 0 items with a siteURI");
+  Assert.notEqual(detectedLiveBookmarks.filter(lb => !lb.siteURI).length, 0,
+                  "Should have more than 0 items without a siteURI");
+  Assert.equal(detectedLiveBookmarks.filter(lb => lb.feedURI).length, 7,
+               "All of them should have a feed URI");
+  info(JSON.stringify(detectedLiveBookmarks));
+  Assert.deepEqual(detectedLiveBookmarks.map(bm => bm.index), [8, 7, 6, 4, 2, 1, 0],
+                   "Should have sorted the items correctly.");
+});
+
+// Test that we write sane OPML for some live bookmarks.
+add_task(async function check_opml_writing() {
+  let bsPass = ChromeUtils.import("resource:///modules/LiveBookmarkMigrator.jsm", {});
+  let oldFile = bsPass.OS.File;
+  registerCleanupFunction(() => { bsPass.OS.File = oldFile; });
+
+  let lastWriteArgs = null;
+  bsPass.OS.File = {
+    writeAtomic() {
+      lastWriteArgs = Array.from(arguments);
+    },
+    openUnique() {
+      return {file: {close() {}}, path: "foopy.opml"};
+    },
+  };
+  let livemarks = [
+    {feedURI: new URL("https://example.com/feed"), siteURI: new URL("https://example.com/"), title: "My funky feed"},
+    {feedURI: new URL("https://example.com/otherfeed"), title: "My other feed"},
+  ];
+  await LiveBookmarkMigrator._writeOPML(livemarks);
+  let expectedOPML = `<?xml version="1.0"?>
+<opml version="1.0"><head><title>LiveBookmarkMigratorTest Live Bookmarks</title></head><body>
+<outline type="rss" title="My funky feed" text="My funky feed" xmlUrl="https://example.com/feed" htmlUrl="https://example.com/"/>
+<outline type="rss" title="My other feed" text="My other feed" xmlUrl="https://example.com/otherfeed"/>
+</body></opml>`;
+  Assert.deepEqual(lastWriteArgs, ["foopy.opml", expectedOPML, {encoding: "utf-8"}], "Should have tried to write the right thing.");
+});
+
+// Check all the live bookmarks have been removed, and where they have site URIs, replaced:
+add_task(async function check_replace_bookmarks_correctly() {
+  let oldLiveBookmarks = await LiveBookmarkMigrator._fetch();
+  await LiveBookmarkMigrator._transformBookmarks(oldLiveBookmarks);
+
+  // Check all the remaining bookmarks are not live bookmarks anymore:
+  let newBookmarkState = await PlacesUtils.promiseBookmarksTree(PlacesUtils.bookmarks.toolbarGuid);
+  function checkNotALiveBookmark(bm) {
+    Assert.ok(!bm.annos, "Bookmark " + bm.title + " shouldn't be a live bookmark");
+  }
+  function iterate(node, fn) {
+    fn(node);
+    if (node.children) {
+      node.children.forEach(fn);
+    }
+  }
+  iterate(newBookmarkState, checkNotALiveBookmark);
+  Assert.equal((await LiveBookmarkMigrator._fetch()).length, 0, "Migrator should no longer find live bookmarks");
+
+  info(JSON.stringify(newBookmarkState));
+  // Check that all the old live bookmarks have been removed, and where appropriate, replaced:
+  for (let bm of oldLiveBookmarks) {
+    let replacements = await PlacesUtils.bookmarks.search({title: bm.title});
+    let replacement = replacements && replacements[0];
+    if (!bm.title.includes("Default live bookmark")) {
+      if (replacement) {
+        Assert.equal(bm.title, replacement.title, "Found item should have same title");
+        Assert.equal(bm.siteURI || bm.feedURI, replacement.url.href, "Found item should have matching URL");
+        Assert.equal(bm.index, replacement.index, "Found item should have same position");
+        Assert.equal(bm.parentGuid, replacement.parentGuid, "Found item should have same parent");
+      } else {
+        Assert.ok(false, "Oy! No replacement for `" + bm.title + "` but we expected one!");
+      }
+    } else {
+      Assert.ok(!replacement, "Shouldn't have kept the default bookmark items");
+    }
+  }
+});
+
--- a/browser/modules/test/unit/xpcshell.ini
+++ b/browser/modules/test/unit/xpcshell.ini
@@ -1,10 +1,11 @@
 [DEFAULT]
 head =
 firefox-appdir = browser
 skip-if = toolkit == 'android'
 
 [test_E10SUtils_nested_URIs.js]
 [test_HomePage.js]
+[test_LiveBookmarkMigrator.js]
 [test_Sanitizer_interrupted.js]
 [test_SitePermissions.js]
 [test_LaterRun.js]
--- a/dom/base/test/browser_force_process_selector.js
+++ b/dom/base/test/browser_force_process_selector.js
@@ -1,23 +1,20 @@
 "use strict";
 
 const CONTENT_CREATED = "ipc:content-created";
 
 // Make sure that BTU.withNewTab({ ..., forceNewProcess: true }) loads
 // new tabs in their own process.
 async function spawnNewAndTest(recur, pids) {
-  let processCreated = TestUtils.topicObserved(CONTENT_CREATED);
   await BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank", forceNewProcess: true },
                                     async function(browser) {
-      // Make sure our new browser is in its own process. The processCreated
-      // promise should have already resolved by this point.
-      await processCreated;
+      // Make sure our new browser is in its own process.
       let newPid = browser.frameLoader.tabParent.osPid;
-      ok(!pids.has(newPid), "new tab is in its own process");
+      ok(!pids.has(newPid), "new tab is in its own process: " + recur);
       pids.add(newPid);
 
       if (recur) {
         await spawnNewAndTest(recur - 1, pids);
       } else {
         let observer = () => {
           ok(false, "shouldn't have created a new process");
         };
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -1109,23 +1109,28 @@ DOMInterfaces = {
     'headerFile': 'WebGLActiveInfo.h'
 },
 
 'WebGLBuffer': {
     'nativeType': 'mozilla::WebGLBuffer',
     'headerFile': 'WebGLBuffer.h'
 },
 
-'WEBGL_compressed_texture_astc': {
-    'nativeType': 'mozilla::WebGLExtensionCompressedTextureASTC',
+'EXT_texture_compression_bptc': {
+    'nativeType': 'mozilla::WebGLExtensionCompressedTextureBPTC',
     'headerFile': 'WebGLExtensions.h'
 },
 
-'WEBGL_compressed_texture_atc': {
-    'nativeType': 'mozilla::WebGLExtensionCompressedTextureATC',
+'EXT_texture_compression_rgtc': {
+    'nativeType': 'mozilla::WebGLExtensionCompressedTextureRGTC',
+    'headerFile': 'WebGLExtensions.h'
+},
+
+'WEBGL_compressed_texture_astc': {
+    'nativeType': 'mozilla::WebGLExtensionCompressedTextureASTC',
     'headerFile': 'WebGLExtensions.h'
 },
 
 'WEBGL_compressed_texture_etc': {
     'nativeType': 'mozilla::WebGLExtensionCompressedTextureES3',
     'headerFile': 'WebGLExtensions.h'
 },
 
--- a/dom/canvas/TexUnpackBlob.cpp
+++ b/dom/canvas/TexUnpackBlob.cpp
@@ -8,16 +8,17 @@
 #include "GLBlitHelper.h"
 #include "GLContext.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/HTMLCanvasElement.h"
 #include "mozilla/RefPtr.h"
 #include "nsLayoutUtils.h"
 #include "WebGLBuffer.h"
 #include "WebGLContext.h"
+#include "WebGLFormats.h"
 #include "WebGLTexelConversions.h"
 #include "WebGLTexture.h"
 
 namespace mozilla {
 namespace webgl {
 
 static bool
 IsPIValidForDOM(const webgl::PackingInfo& pi)
--- a/dom/canvas/WebGL2ContextRenderbuffers.cpp
+++ b/dom/canvas/WebGL2ContextRenderbuffers.cpp
@@ -3,16 +3,17 @@
 /* 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 "WebGL2Context.h"
 
 #include "GLContext.h"
 #include "WebGLContextUtils.h"
+#include "WebGLFormats.h"
 
 namespace mozilla {
 
 void
 WebGL2Context::GetInternalformatParameter(JSContext* cx, GLenum target,
                                           GLenum internalformat, GLenum pname,
                                           JS::MutableHandleValue retval,
                                           ErrorResult& out_rv)
--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -58,16 +58,17 @@
 // Local
 #include "CanvasUtils.h"
 #include "WebGL1Context.h"
 #include "WebGLActiveInfo.h"
 #include "WebGLBuffer.h"
 #include "WebGLContextLossHandler.h"
 #include "WebGLContextUtils.h"
 #include "WebGLExtensions.h"
+#include "WebGLFormats.h"
 #include "WebGLFramebuffer.h"
 #include "WebGLMemoryTracker.h"
 #include "WebGLObjectModel.h"
 #include "WebGLProgram.h"
 #include "WebGLQuery.h"
 #include "WebGLSampler.h"
 #include "WebGLShader.h"
 #include "WebGLSync.h"
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -29,17 +29,16 @@
 #include "SurfaceTypes.h"
 #include "ScopedGLHelpers.h"
 #include "TexUnpackBlob.h"
 
 // Local
 #include "CacheMap.h"
 #include "WebGLContextLossHandler.h"
 #include "WebGLContextUnchecked.h"
-#include "WebGLFormats.h"
 #include "WebGLObjectModel.h"
 #include "WebGLStrongTypes.h"
 #include "WebGLTexture.h"
 
 // Generated
 #include "nsIDOMEventListener.h"
 #include "nsICanvasRenderingContextInternal.h"
 #include "nsIObserver.h"
@@ -97,16 +96,19 @@ class VRLayerChild;
 namespace gl {
 class GLScreenBuffer;
 class MozFramebuffer;
 } // namespace gl
 
 namespace webgl {
 class AvailabilityRunnable;
 struct CachedDrawFetchLimits;
+struct FormatInfo;
+class FormatUsageAuthority;
+struct FormatUsageInfo;
 struct LinkedProgramInfo;
 class ShaderValidator;
 class TexUnpackBlob;
 struct UniformInfo;
 struct UniformBlockInfo;
 } // namespace webgl
 
 WebGLTexelFormat GetWebGLTexelFormat(TexInternalFormat format);
@@ -283,20 +285,21 @@ class WebGLContext
 {
     friend class ScopedDrawCallWrapper;
     friend class ScopedDrawWithTransformFeedback;
     friend class ScopedFakeVertexAttrib0;
     friend class ScopedFBRebinder;
     friend class WebGL2Context;
     friend class WebGLContextUserData;
     friend class WebGLExtensionCompressedTextureASTC;
-    friend class WebGLExtensionCompressedTextureATC;
+    friend class WebGLExtensionCompressedTextureBPTC;
     friend class WebGLExtensionCompressedTextureES3;
     friend class WebGLExtensionCompressedTextureETC1;
     friend class WebGLExtensionCompressedTexturePVRTC;
+    friend class WebGLExtensionCompressedTextureRGTC;
     friend class WebGLExtensionCompressedTextureS3TC;
     friend class WebGLExtensionCompressedTextureS3TC_SRGB;
     friend class WebGLExtensionDepthTexture;
     friend class WebGLExtensionDisjointTimerQuery;
     friend class WebGLExtensionDrawBuffers;
     friend class WebGLExtensionLoseContext;
     friend class WebGLExtensionMOZDebug;
     friend class WebGLExtensionVertexArray;
--- a/dom/canvas/WebGLContextExtensions.cpp
+++ b/dom/canvas/WebGLContextExtensions.cpp
@@ -34,29 +34,30 @@ WebGLContext::GetExtensionString(WebGLEx
 
         WEBGL_EXTENSION_IDENTIFIER(ANGLE_instanced_arrays)
         WEBGL_EXTENSION_IDENTIFIER(EXT_blend_minmax)
         WEBGL_EXTENSION_IDENTIFIER(EXT_color_buffer_float)
         WEBGL_EXTENSION_IDENTIFIER(EXT_color_buffer_half_float)
         WEBGL_EXTENSION_IDENTIFIER(EXT_frag_depth)
         WEBGL_EXTENSION_IDENTIFIER(EXT_shader_texture_lod)
         WEBGL_EXTENSION_IDENTIFIER(EXT_sRGB)
+        WEBGL_EXTENSION_IDENTIFIER(EXT_texture_compression_bptc)
+        WEBGL_EXTENSION_IDENTIFIER(EXT_texture_compression_rgtc)
         WEBGL_EXTENSION_IDENTIFIER(EXT_texture_filter_anisotropic)
         WEBGL_EXTENSION_IDENTIFIER(EXT_disjoint_timer_query)
         WEBGL_EXTENSION_IDENTIFIER(MOZ_debug)
         WEBGL_EXTENSION_IDENTIFIER(OES_element_index_uint)
         WEBGL_EXTENSION_IDENTIFIER(OES_standard_derivatives)
         WEBGL_EXTENSION_IDENTIFIER(OES_texture_float)
         WEBGL_EXTENSION_IDENTIFIER(OES_texture_float_linear)
         WEBGL_EXTENSION_IDENTIFIER(OES_texture_half_float)
         WEBGL_EXTENSION_IDENTIFIER(OES_texture_half_float_linear)
         WEBGL_EXTENSION_IDENTIFIER(OES_vertex_array_object)
         WEBGL_EXTENSION_IDENTIFIER(WEBGL_color_buffer_float)
         WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_astc)
-        WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_atc)
         WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_etc)
         WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_etc1)
         WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_pvrtc)
         WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_s3tc)
         WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_s3tc_srgb)
         WEBGL_EXTENSION_IDENTIFIER(WEBGL_debug_renderer_info)
         WEBGL_EXTENSION_IDENTIFIER(WEBGL_debug_shaders)
         WEBGL_EXTENSION_IDENTIFIER(WEBGL_depth_texture)
@@ -115,28 +116,36 @@ WebGLContext::IsExtensionSupported(WebGL
 {
     if (mDisableExtensions)
         return false;
 
     // Extensions for both WebGL 1 and 2.
     switch (ext) {
     // In alphabetical order
     // EXT_
+    case WebGLExtensionID::EXT_texture_compression_bptc:
+        if (!gfxPrefs::WebGLDraftExtensionsEnabled())
+            return false;
+        return WebGLExtensionCompressedTextureBPTC::IsSupported(this);
+
+    case WebGLExtensionID::EXT_texture_compression_rgtc:
+        if (!gfxPrefs::WebGLDraftExtensionsEnabled())
+            return false;
+        return WebGLExtensionCompressedTextureRGTC::IsSupported(this);
+
     case WebGLExtensionID::EXT_texture_filter_anisotropic:
         return gl->IsExtensionSupported(gl::GLContext::EXT_texture_filter_anisotropic);
 
     // OES_
     case WebGLExtensionID::OES_texture_float_linear:
         return gl->IsSupported(gl::GLFeature::texture_float_linear);
 
     // WEBGL_
     case WebGLExtensionID::WEBGL_compressed_texture_astc:
         return WebGLExtensionCompressedTextureASTC::IsSupported(this);
-    case WebGLExtensionID::WEBGL_compressed_texture_atc:
-        return gl->IsExtensionSupported(gl::GLContext::AMD_compressed_ATC_texture);
     case WebGLExtensionID::WEBGL_compressed_texture_etc:
         return gl->IsSupported(gl::GLFeature::ES3_compatibility) &&
                !gl->IsANGLE();
     case WebGLExtensionID::WEBGL_compressed_texture_etc1:
         return gl->IsExtensionSupported(gl::GLContext::OES_compressed_ETC1_RGB8_texture) &&
                !gl->IsANGLE();
     case WebGLExtensionID::WEBGL_compressed_texture_pvrtc:
         return gl->IsExtensionSupported(gl::GLContext::IMG_texture_compression_pvrtc);
@@ -340,16 +349,22 @@ WebGLContext::EnableExtension(WebGLExten
         obj = new WebGLExtensionFragDepth(this);
         break;
     case WebGLExtensionID::EXT_shader_texture_lod:
         obj = new WebGLExtensionShaderTextureLod(this);
         break;
     case WebGLExtensionID::EXT_sRGB:
         obj = new WebGLExtensionSRGB(this);
         break;
+    case WebGLExtensionID::EXT_texture_compression_bptc:
+        obj = new WebGLExtensionCompressedTextureBPTC(this);
+        break;
+    case WebGLExtensionID::EXT_texture_compression_rgtc:
+        obj = new WebGLExtensionCompressedTextureRGTC(this);
+        break;
     case WebGLExtensionID::EXT_texture_filter_anisotropic:
         obj = new WebGLExtensionTextureFilterAnisotropic(this);
         break;
 
     // MOZ_
     case WebGLExtensionID::MOZ_debug:
         obj = new WebGLExtensionMOZDebug(this);
         break;
@@ -379,19 +394,16 @@ WebGLContext::EnableExtension(WebGLExten
 
     // WEBGL_
     case WebGLExtensionID::WEBGL_color_buffer_float:
         obj = new WebGLExtensionColorBufferFloat(this);
         break;
     case WebGLExtensionID::WEBGL_compressed_texture_astc:
         obj = new WebGLExtensionCompressedTextureASTC(this);
         break;
-    case WebGLExtensionID::WEBGL_compressed_texture_atc:
-        obj = new WebGLExtensionCompressedTextureATC(this);
-        break;
     case WebGLExtensionID::WEBGL_compressed_texture_etc:
         obj = new WebGLExtensionCompressedTextureES3(this);
         break;
     case WebGLExtensionID::WEBGL_compressed_texture_etc1:
         obj = new WebGLExtensionCompressedTextureETC1(this);
         break;
     case WebGLExtensionID::WEBGL_compressed_texture_pvrtc:
         obj = new WebGLExtensionCompressedTexturePVRTC(this);
--- a/dom/canvas/WebGLContextFramebufferOperations.cpp
+++ b/dom/canvas/WebGLContextFramebufferOperations.cpp
@@ -1,19 +1,21 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* 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 "WebGLContext.h"
-#include "WebGLTexture.h"
-#include "WebGLRenderbuffer.h"
-#include "WebGLFramebuffer.h"
+
 #include "GLContext.h"
 #include "GLScreenBuffer.h"
+#include "WebGLFormats.h"
+#include "WebGLFramebuffer.h"
+#include "WebGLRenderbuffer.h"
+#include "WebGLTexture.h"
 
 namespace mozilla {
 
 void
 WebGLContext::Clear(GLbitfield mask)
 {
     const FuncScope funcScope(*this, "clear");
     if (IsContextLost())
--- a/dom/canvas/WebGLContextUtils.cpp
+++ b/dom/canvas/WebGLContextUtils.cpp
@@ -276,19 +276,16 @@ WebGLContext::ErrorName(GLenum error)
 // This version is fallible and will return nullptr if unrecognized.
 const char*
 GetEnumName(const GLenum val, const char* const defaultRet)
 {
     switch (val) {
 #define XX(x) case LOCAL_GL_##x: return #x
         XX(NONE);
         XX(ALPHA);
-        XX(ATC_RGB);
-        XX(ATC_RGBA_EXPLICIT_ALPHA);
-        XX(ATC_RGBA_INTERPOLATED_ALPHA);
         XX(COMPRESSED_RGBA_PVRTC_2BPPV1);
         XX(COMPRESSED_RGBA_PVRTC_4BPPV1);
         XX(COMPRESSED_RGBA_S3TC_DXT1_EXT);
         XX(COMPRESSED_RGBA_S3TC_DXT3_EXT);
         XX(COMPRESSED_RGBA_S3TC_DXT5_EXT);
         XX(COMPRESSED_RGB_PVRTC_2BPPV1);
         XX(COMPRESSED_RGB_PVRTC_4BPPV1);
         XX(COMPRESSED_RGB_S3TC_DXT1_EXT);
@@ -630,59 +627,16 @@ EnumString(const GLenum val)
 void
 WebGLContext::ErrorInvalidEnumArg(const char* argName, GLenum val) const
 {
     nsCString enumName;
     EnumName(val, &enumName);
     ErrorInvalidEnum("Bad `%s`: %s", argName, enumName.BeginReading());
 }
 
-bool
-IsCompressedTextureFormat(GLenum format)
-{
-    switch (format) {
-    case LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
-    case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-    case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
-    case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
-    case LOCAL_GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
-    case LOCAL_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
-    case LOCAL_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
-    case LOCAL_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
-    case LOCAL_GL_ATC_RGB:
-    case LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA:
-    case LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA:
-    case LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1:
-    case LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1:
-    case LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1:
-    case LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1:
-    case LOCAL_GL_ETC1_RGB8_OES:
-    case LOCAL_GL_COMPRESSED_R11_EAC:
-    case LOCAL_GL_COMPRESSED_SIGNED_R11_EAC:
-    case LOCAL_GL_COMPRESSED_RG11_EAC:
-    case LOCAL_GL_COMPRESSED_SIGNED_RG11_EAC:
-    case LOCAL_GL_COMPRESSED_RGB8_ETC2:
-    case LOCAL_GL_COMPRESSED_SRGB8_ETC2:
-    case LOCAL_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
-    case LOCAL_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
-    case LOCAL_GL_COMPRESSED_RGBA8_ETC2_EAC:
-    case LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
-        return true;
-    default:
-        return false;
-    }
-}
-
-
-bool
-IsTextureFormatCompressed(TexInternalFormat format)
-{
-    return IsCompressedTextureFormat(format.get());
-}
-
 GLenum
 WebGLContext::GetAndFlushUnderlyingGLErrors() const
 {
     // Get and clear GL error in ALL cases.
     GLenum error = gl->fGetError();
 
     // Only store in mUnderlyingGLError if is hasn't already recorded an
     // error.
--- a/dom/canvas/WebGLExtensionColorBufferFloat.cpp
+++ b/dom/canvas/WebGLExtensionColorBufferFloat.cpp
@@ -4,20 +4,16 @@
 
 #include "WebGLExtensions.h"
 
 #include "GLContext.h"
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
 #include "WebGLContext.h"
 #include "WebGLFormats.h"
 
-#ifdef FOO
-#error FOO is already defined! We use FOO() macros to keep things succinct in this file.
-#endif
-
 namespace mozilla {
 
 WebGLExtensionColorBufferFloat::WebGLExtensionColorBufferFloat(WebGLContext* webgl)
     : WebGLExtensionBase(webgl)
 {
     MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported.");
 
     auto& fua = webgl->mFormatUsage;
--- a/dom/canvas/WebGLExtensionColorBufferHalfFloat.cpp
+++ b/dom/canvas/WebGLExtensionColorBufferHalfFloat.cpp
@@ -4,20 +4,16 @@
 
 #include "WebGLExtensions.h"
 
 #include "GLContext.h"
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
 #include "WebGLContext.h"
 #include "WebGLFormats.h"
 
-#ifdef FOO
-#error FOO is already defined! We use FOO() macros to keep things succinct in this file.
-#endif
-
 namespace mozilla {
 
 WebGLExtensionColorBufferHalfFloat::WebGLExtensionColorBufferHalfFloat(WebGLContext* webgl)
     : WebGLExtensionBase(webgl)
 {
     MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported.");
 
     auto& fua = webgl->mFormatUsage;
--- a/dom/canvas/WebGLExtensionCompressedTextureASTC.cpp
+++ b/dom/canvas/WebGLExtensionCompressedTextureASTC.cpp
@@ -2,16 +2,17 @@
  * 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 "WebGLExtensions.h"
 
 #include "GLContext.h"
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
 #include "WebGLContext.h"
+#include "WebGLFormats.h"
 
 namespace mozilla {
 
 WebGLExtensionCompressedTextureASTC::WebGLExtensionCompressedTextureASTC(WebGLContext* webgl)
     : WebGLExtensionBase(webgl)
 {
     MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported.");
 
deleted file mode 100644
--- a/dom/canvas/WebGLExtensionCompressedTextureATC.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/* 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 "WebGLExtensions.h"
-
-#include "GLContext.h"
-#include "mozilla/dom/WebGLRenderingContextBinding.h"
-#include "WebGLContext.h"
-
-#ifdef FOO
-#error FOO is already defined! We use FOO() macros to keep things succinct in this file.
-#endif
-
-namespace mozilla {
-
-WebGLExtensionCompressedTextureATC::WebGLExtensionCompressedTextureATC(WebGLContext* webgl)
-    : WebGLExtensionBase(webgl)
-{
-    RefPtr<WebGLContext> webgl_ = webgl; // Bug 1201275
-    const auto fnAdd = [&webgl_](GLenum sizedFormat, webgl::EffectiveFormat effFormat) {
-        auto& fua = webgl_->mFormatUsage;
-
-        auto usage = fua->EditUsage(effFormat);
-        usage->isFilterable = true;
-        fua->AllowSizedTexFormat(sizedFormat, usage);
-
-        webgl_->mCompressedTextureFormats.AppendElement(sizedFormat);
-    };
-
-#define FOO(x) LOCAL_GL_ ## x, webgl::EffectiveFormat::x
-
-    fnAdd(FOO(ATC_RGB_AMD));
-    fnAdd(FOO(ATC_RGBA_EXPLICIT_ALPHA_AMD));
-    fnAdd(FOO(ATC_RGBA_INTERPOLATED_ALPHA_AMD));
-
-#undef FOO
-}
-
-WebGLExtensionCompressedTextureATC::~WebGLExtensionCompressedTextureATC()
-{
-}
-
-IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionCompressedTextureATC, WEBGL_compressed_texture_atc)
-
-} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/canvas/WebGLExtensionCompressedTextureBPTC.cpp
@@ -0,0 +1,49 @@
+/* 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 "WebGLExtensions.h"
+
+#include "GLContext.h"
+#include "mozilla/dom/WebGLRenderingContextBinding.h"
+#include "WebGLContext.h"
+#include "WebGLFormats.h"
+
+namespace mozilla {
+
+WebGLExtensionCompressedTextureBPTC::WebGLExtensionCompressedTextureBPTC(WebGLContext* const webgl)
+    : WebGLExtensionBase(webgl)
+{
+    MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported.");
+
+    auto& fua = webgl->mFormatUsage;
+
+    const auto fnAdd = [&](const GLenum sizedFormat,
+                           const webgl::EffectiveFormat effFormat)
+    {
+        auto usage = fua->EditUsage(effFormat);
+        usage->isFilterable = true;
+        fua->AllowSizedTexFormat(sizedFormat, usage);
+
+        webgl->mCompressedTextureFormats.AppendElement(sizedFormat);
+    };
+
+#define _(X) LOCAL_GL_ ## X, webgl::EffectiveFormat::X
+
+    fnAdd(_(COMPRESSED_RGBA_BPTC_UNORM));
+    fnAdd(_(COMPRESSED_SRGB_ALPHA_BPTC_UNORM));
+    fnAdd(_(COMPRESSED_RGB_BPTC_SIGNED_FLOAT));
+    fnAdd(_(COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT));
+
+#undef _
+}
+
+bool
+WebGLExtensionCompressedTextureBPTC::IsSupported(const WebGLContext* const webgl)
+{
+    return webgl->gl->IsSupported(gl::GLFeature::texture_compression_bptc);
+}
+
+IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionCompressedTextureBPTC, EXT_texture_compression_bptc)
+
+} // namespace mozilla
--- a/dom/canvas/WebGLExtensionCompressedTextureES3.cpp
+++ b/dom/canvas/WebGLExtensionCompressedTextureES3.cpp
@@ -2,20 +2,17 @@
  * 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 "WebGLExtensions.h"
 
 #include "GLContext.h"
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
 #include "WebGLContext.h"
-
-#ifdef FOO
-#error FOO is already defined! We use FOO() macros to keep things succinct in this file.
-#endif
+#include "WebGLFormats.h"
 
 namespace mozilla {
 
 WebGLExtensionCompressedTextureES3::WebGLExtensionCompressedTextureES3(WebGLContext* webgl)
     : WebGLExtensionBase(webgl)
 {
     // GLES 3.0.4, p147, table 3.19
     // GLES 3.0.4, p286+, $C.1 "ETC Compressed Texture Image Formats"
--- a/dom/canvas/WebGLExtensionCompressedTextureETC1.cpp
+++ b/dom/canvas/WebGLExtensionCompressedTextureETC1.cpp
@@ -2,20 +2,17 @@
  * 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 "WebGLExtensions.h"
 
 #include "GLContext.h"
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
 #include "WebGLContext.h"
-
-#ifdef FOO
-#error FOO is already defined! We use FOO() macros to keep things succinct in this file.
-#endif
+#include "WebGLFormats.h"
 
 namespace mozilla {
 
 WebGLExtensionCompressedTextureETC1::WebGLExtensionCompressedTextureETC1(WebGLContext* webgl)
     : WebGLExtensionBase(webgl)
 {
     RefPtr<WebGLContext> webgl_ = webgl; // Bug 1201275
     const auto fnAdd = [&webgl_](GLenum sizedFormat, webgl::EffectiveFormat effFormat) {
--- a/dom/canvas/WebGLExtensionCompressedTexturePVRTC.cpp
+++ b/dom/canvas/WebGLExtensionCompressedTexturePVRTC.cpp
@@ -2,20 +2,17 @@
  * 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 "WebGLExtensions.h"
 
 #include "GLContext.h"
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
 #include "WebGLContext.h"
-
-#ifdef FOO
-#error FOO is already defined! We use FOO() macros to keep things succinct in this file.
-#endif
+#include "WebGLFormats.h"
 
 namespace mozilla {
 
 WebGLExtensionCompressedTexturePVRTC::WebGLExtensionCompressedTexturePVRTC(WebGLContext* webgl)
     : WebGLExtensionBase(webgl)
 {
     RefPtr<WebGLContext> webgl_ = webgl; // Bug 1201275
     const auto fnAdd = [&webgl_](GLenum sizedFormat, webgl::EffectiveFormat effFormat) {
new file mode 100644
--- /dev/null
+++ b/dom/canvas/WebGLExtensionCompressedTextureRGTC.cpp
@@ -0,0 +1,49 @@
+/* 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 "WebGLExtensions.h"
+
+#include "GLContext.h"
+#include "mozilla/dom/WebGLRenderingContextBinding.h"
+#include "WebGLContext.h"
+#include "WebGLFormats.h"
+
+namespace mozilla {
+
+WebGLExtensionCompressedTextureRGTC::WebGLExtensionCompressedTextureRGTC(WebGLContext* const webgl)
+    : WebGLExtensionBase(webgl)
+{
+    MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported.");
+
+    auto& fua = webgl->mFormatUsage;
+
+    const auto fnAdd = [&](const GLenum sizedFormat,
+                           const webgl::EffectiveFormat effFormat)
+    {
+        auto usage = fua->EditUsage(effFormat);
+        usage->isFilterable = true;
+        fua->AllowSizedTexFormat(sizedFormat, usage);
+
+        webgl->mCompressedTextureFormats.AppendElement(sizedFormat);
+    };
+
+#define _(X) LOCAL_GL_ ## X, webgl::EffectiveFormat::X
+
+    fnAdd(_(COMPRESSED_RED_RGTC1));
+    fnAdd(_(COMPRESSED_SIGNED_RED_RGTC1));
+    fnAdd(_(COMPRESSED_RG_RGTC2));
+    fnAdd(_(COMPRESSED_SIGNED_RG_RGTC2));
+
+#undef _
+}
+
+bool
+WebGLExtensionCompressedTextureRGTC::IsSupported(const WebGLContext* const webgl)
+{
+    return webgl->gl->IsSupported(gl::GLFeature::texture_compression_rgtc);
+}
+
+IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionCompressedTextureRGTC, EXT_texture_compression_rgtc)
+
+} // namespace mozilla
--- a/dom/canvas/WebGLExtensionCompressedTextureS3TC.cpp
+++ b/dom/canvas/WebGLExtensionCompressedTextureS3TC.cpp
@@ -2,20 +2,17 @@
  * 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 "WebGLExtensions.h"
 
 #include "GLContext.h"
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
 #include "WebGLContext.h"
-
-#ifdef FOO
-#error FOO is already defined! We use FOO() macros to keep things succinct in this file.
-#endif
+#include "WebGLFormats.h"
 
 namespace mozilla {
 
 WebGLExtensionCompressedTextureS3TC::WebGLExtensionCompressedTextureS3TC(WebGLContext* webgl)
     : WebGLExtensionBase(webgl)
 {
     RefPtr<WebGLContext> webgl_ = webgl; // Bug 1201275
     const auto fnAdd = [&webgl_](GLenum sizedFormat, webgl::EffectiveFormat effFormat) {
--- a/dom/canvas/WebGLExtensionCompressedTextureS3TC_SRGB.cpp
+++ b/dom/canvas/WebGLExtensionCompressedTextureS3TC_SRGB.cpp
@@ -2,20 +2,17 @@
  * 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 "WebGLExtensions.h"
 
 #include "GLContext.h"
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
 #include "WebGLContext.h"
-
-#ifdef FOO
-#error FOO is already defined! We use FOO() macros to keep things succinct in this file.
-#endif
+#include "WebGLFormats.h"
 
 namespace mozilla {
 
 WebGLExtensionCompressedTextureS3TC_SRGB::WebGLExtensionCompressedTextureS3TC_SRGB(WebGLContext* webgl)
     : WebGLExtensionBase(webgl)
 {
     RefPtr<WebGLContext> webgl_ = webgl; // Bug 1201275
     const auto fnAdd = [&webgl_](GLenum sizedFormat, webgl::EffectiveFormat effFormat) {
--- a/dom/canvas/WebGLExtensions.h
+++ b/dom/canvas/WebGLExtensions.h
@@ -74,22 +74,23 @@ public:
 
     void GetSupportedProfiles(dom::Nullable< nsTArray<nsString> >& retval) const;
 
     static bool IsSupported(const WebGLContext* webgl);
 
     DECL_WEBGL_EXTENSION_GOOP
 };
 
-class WebGLExtensionCompressedTextureATC
+class WebGLExtensionCompressedTextureBPTC final
     : public WebGLExtensionBase
 {
 public:
-    explicit WebGLExtensionCompressedTextureATC(WebGLContext*);
-    virtual ~WebGLExtensionCompressedTextureATC();
+    explicit WebGLExtensionCompressedTextureBPTC(WebGLContext* webgl);
+
+    static bool IsSupported(const WebGLContext* webgl);
 
     DECL_WEBGL_EXTENSION_GOOP
 };
 
 class WebGLExtensionCompressedTextureES3
     : public WebGLExtensionBase
 {
 public:
@@ -114,16 +115,27 @@ class WebGLExtensionCompressedTexturePVR
 {
 public:
     explicit WebGLExtensionCompressedTexturePVRTC(WebGLContext*);
     virtual ~WebGLExtensionCompressedTexturePVRTC();
 
     DECL_WEBGL_EXTENSION_GOOP
 };
 
+class WebGLExtensionCompressedTextureRGTC final
+    : public WebGLExtensionBase
+{
+public:
+    explicit WebGLExtensionCompressedTextureRGTC(WebGLContext* webgl);
+
+    static bool IsSupported(const WebGLContext* webgl);
+
+    DECL_WEBGL_EXTENSION_GOOP
+};
+
 class WebGLExtensionCompressedTextureS3TC
     : public WebGLExtensionBase
 {
 public:
     explicit WebGLExtensionCompressedTextureS3TC(WebGLContext*);
     virtual ~WebGLExtensionCompressedTextureS3TC();
 
     static bool IsSupported(const WebGLContext*);
--- a/dom/canvas/WebGLFormats.cpp
+++ b/dom/canvas/WebGLFormats.cpp
@@ -6,20 +6,16 @@
 #include "WebGLFormats.h"
 
 #include "gfxPrefs.h"
 #include "GLContext.h"
 #include "GLDefs.h"
 #include "mozilla/gfx/Logging.h"
 #include "mozilla/StaticMutex.h"
 
-#ifdef FOO
-#error FOO is already defined! We use FOO() macros to keep things succinct in this file.
-#endif
-
 namespace mozilla {
 namespace webgl {
 
 template<typename K, typename V, typename K2, typename V2>
 static inline void
 AlwaysInsert(std::map<K,V>& dest, const K2& key, const V2& val)
 {
     auto res = dest.insert({ key, val });
@@ -97,20 +93,27 @@ InitCompressedFormatInfo()
     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC         , 128, 4, 4, CompressionFamily::ES3);
     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_R11_EAC                       ,  64, 4, 4, CompressionFamily::ES3);
     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RG11_EAC                      , 128, 4, 4, CompressionFamily::ES3);
     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SIGNED_R11_EAC                ,  64, 4, 4, CompressionFamily::ES3);
     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SIGNED_RG11_EAC               , 128, 4, 4, CompressionFamily::ES3);
     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 ,  64, 4, 4, CompressionFamily::ES3);
     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,  64, 4, 4, CompressionFamily::ES3);
 
-    // AMD_compressed_ATC_texture
-    AddCompressedFormatInfo(EffectiveFormat::ATC_RGB_AMD                    ,  64, 4, 4, CompressionFamily::ATC);
-    AddCompressedFormatInfo(EffectiveFormat::ATC_RGBA_EXPLICIT_ALPHA_AMD    , 128, 4, 4, CompressionFamily::ATC);
-    AddCompressedFormatInfo(EffectiveFormat::ATC_RGBA_INTERPOLATED_ALPHA_AMD, 128, 4, 4, CompressionFamily::ATC);
+    // EXT_texture_compression_bptc
+    AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_BPTC_UNORM        , 16*8, 4, 4, CompressionFamily::BPTC);
+    AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB_ALPHA_BPTC_UNORM  , 16*8, 4, 4, CompressionFamily::BPTC);
+    AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB_BPTC_SIGNED_FLOAT  , 16*8, 4, 4, CompressionFamily::BPTC);
+    AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, 16*8, 4, 4, CompressionFamily::BPTC);
+
+    // EXT_texture_compression_rgtc
+    AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RED_RGTC1       ,  8*8, 4, 4, CompressionFamily::RGTC);
+    AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SIGNED_RED_RGTC1,  8*8, 4, 4, CompressionFamily::RGTC);
+    AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RG_RGTC2        , 16*8, 4, 4, CompressionFamily::RGTC);
+    AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SIGNED_RG_RGTC2 , 16*8, 4, 4, CompressionFamily::RGTC);
 
     // EXT_texture_compression_s3tc
     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB_S3TC_DXT1_EXT ,  64, 4, 4, CompressionFamily::S3TC);
     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT1_EXT,  64, 4, 4, CompressionFamily::S3TC);
     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT3_EXT, 128, 4, 4, CompressionFamily::S3TC);
     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT5_EXT, 128, 4, 4, CompressionFamily::S3TC);
 
     // EXT_texture_compression_s3tc_srgb
@@ -313,20 +316,27 @@ InitFormatInfo()
     AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ETC2_EAC         ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
     AddFormatInfo(FOO(COMPRESSED_R11_EAC                       ), 0, 1,0,0,0, 0,0, UnsizedFormat::R   , false, ComponentType::NormUInt);
     AddFormatInfo(FOO(COMPRESSED_RG11_EAC                      ), 0, 1,1,0,0, 0,0, UnsizedFormat::RG  , false, ComponentType::NormUInt);
     AddFormatInfo(FOO(COMPRESSED_SIGNED_R11_EAC                ), 0, 1,0,0,0, 0,0, UnsizedFormat::R   , false, ComponentType::NormInt );
     AddFormatInfo(FOO(COMPRESSED_SIGNED_RG11_EAC               ), 0, 1,1,0,0, 0,0, UnsizedFormat::RG  , false, ComponentType::NormInt );
     AddFormatInfo(FOO(COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     AddFormatInfo(FOO(COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
 
-    // AMD_compressed_ATC_texture
-    AddFormatInfo(FOO(ATC_RGB_AMD                    ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , false, ComponentType::NormUInt);
-    AddFormatInfo(FOO(ATC_RGBA_EXPLICIT_ALPHA_AMD    ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
-    AddFormatInfo(FOO(ATC_RGBA_INTERPOLATED_ALPHA_AMD), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
+    // EXT_texture_compression_bptc
+    AddFormatInfo(FOO(COMPRESSED_RGBA_BPTC_UNORM        ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
+    AddFormatInfo(FOO(COMPRESSED_SRGB_ALPHA_BPTC_UNORM  ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
+    AddFormatInfo(FOO(COMPRESSED_RGB_BPTC_SIGNED_FLOAT  ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , false, ComponentType::Float   );
+    AddFormatInfo(FOO(COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , false, ComponentType::Float   );
+
+    // EXT_texture_compression_rgtc
+    AddFormatInfo(FOO(COMPRESSED_RED_RGTC1       ), 0, 1,0,0,0, 0,0, UnsizedFormat::R , false, ComponentType::NormUInt);
+    AddFormatInfo(FOO(COMPRESSED_SIGNED_RED_RGTC1), 0, 1,0,0,0, 0,0, UnsizedFormat::R , false, ComponentType::NormInt );
+    AddFormatInfo(FOO(COMPRESSED_RG_RGTC2        ), 0, 1,1,0,0, 0,0, UnsizedFormat::RG, false, ComponentType::NormUInt);
+    AddFormatInfo(FOO(COMPRESSED_SIGNED_RG_RGTC2 ), 0, 1,1,0,0, 0,0, UnsizedFormat::RG, false, ComponentType::NormInt );
 
     // EXT_texture_compression_s3tc
     AddFormatInfo(FOO(COMPRESSED_RGB_S3TC_DXT1_EXT ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , false, ComponentType::NormUInt);
     AddFormatInfo(FOO(COMPRESSED_RGBA_S3TC_DXT1_EXT), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     AddFormatInfo(FOO(COMPRESSED_RGBA_S3TC_DXT3_EXT), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     AddFormatInfo(FOO(COMPRESSED_RGBA_S3TC_DXT5_EXT), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
 
     // EXT_texture_compression_s3tc_srgb
--- a/dom/canvas/WebGLFormats.h
+++ b/dom/canvas/WebGLFormats.h
@@ -103,20 +103,27 @@ enum class EffectiveFormat : EffectiveFo
     COMPRESSED_SIGNED_RG11_EAC,
     COMPRESSED_RGB8_ETC2,
     COMPRESSED_SRGB8_ETC2,
     COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
     COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
     COMPRESSED_RGBA8_ETC2_EAC,
     COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
 
-    // AMD_compressed_ATC_texture
-    ATC_RGB_AMD,
-    ATC_RGBA_EXPLICIT_ALPHA_AMD,
-    ATC_RGBA_INTERPOLATED_ALPHA_AMD,
+    // EXT_texture_compression_bptc
+    COMPRESSED_RGBA_BPTC_UNORM,
+    COMPRESSED_SRGB_ALPHA_BPTC_UNORM,
+    COMPRESSED_RGB_BPTC_SIGNED_FLOAT,
+    COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT,
+
+    // EXT_texture_compression_rgtc
+    COMPRESSED_RED_RGTC1,
+    COMPRESSED_SIGNED_RED_RGTC1,
+    COMPRESSED_RG_RGTC2,
+    COMPRESSED_SIGNED_RG_RGTC2,
 
     // EXT_texture_compression_s3tc
     COMPRESSED_RGB_S3TC_DXT1_EXT,
     COMPRESSED_RGBA_S3TC_DXT1_EXT,
     COMPRESSED_RGBA_S3TC_DXT3_EXT,
     COMPRESSED_RGBA_S3TC_DXT5_EXT,
 
     // EXT_texture_sRGB
@@ -206,20 +213,21 @@ enum class ComponentType : uint8_t {
     NormInt,      // RGBA8_SNORM
     NormUInt,     // RGBA8, DEPTH_COMPONENT16
     Float,        // RGBA32F
     Special,      // DEPTH24_STENCIL8
 };
 
 enum class CompressionFamily : uint8_t {
     ASTC,
-    ATC,
+    BPTC,
     ES3, // ETC2 or EAC
     ETC1,
     PVRTC,
+    RGTC,
     S3TC,
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 
 struct CompressedFormatInfo
 {
     const EffectiveFormat effectiveFormat;
--- a/dom/canvas/WebGLRenderbuffer.cpp
+++ b/dom/canvas/WebGLRenderbuffer.cpp
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WebGLRenderbuffer.h"
 
 #include "GLContext.h"
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
 #include "ScopedGLHelpers.h"
 #include "WebGLContext.h"
+#include "WebGLFormats.h"
 #include "WebGLStrongTypes.h"
 #include "WebGLTexture.h"
 
 namespace mozilla {
 
 static GLenum
 DepthFormatForDepthStencilEmu(gl::GLContext* gl)
 {
--- a/dom/canvas/WebGLStrongTypes.h
+++ b/dom/canvas/WebGLStrongTypes.h
@@ -345,17 +345,16 @@ STRONG_GLENUM_BEGIN(TexInternalFormat)
     STRONG_GLENUM_VALUE(COMPRESSED_RGBA_S3TC_DXT1_EXT),
     STRONG_GLENUM_VALUE(COMPRESSED_RGBA_S3TC_DXT3_EXT),
     STRONG_GLENUM_VALUE(COMPRESSED_RGBA_S3TC_DXT5_EXT),
     STRONG_GLENUM_VALUE(COMPRESSED_SRGB_S3TC_DXT1_EXT),
     STRONG_GLENUM_VALUE(COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT),
     STRONG_GLENUM_VALUE(COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT),
     STRONG_GLENUM_VALUE(COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT),
     STRONG_GLENUM_VALUE(DEPTH_STENCIL),
-    STRONG_GLENUM_VALUE(ATC_RGBA_INTERPOLATED_ALPHA),
     STRONG_GLENUM_VALUE(RGBA32F),
     STRONG_GLENUM_VALUE(RGB32F),
     STRONG_GLENUM_VALUE(ALPHA32F_EXT),
     STRONG_GLENUM_VALUE(LUMINANCE32F_EXT),
     STRONG_GLENUM_VALUE(LUMINANCE_ALPHA32F_EXT),
     STRONG_GLENUM_VALUE(RGBA16F),
     STRONG_GLENUM_VALUE(RGB16F),
     STRONG_GLENUM_VALUE(ALPHA16F_EXT),
@@ -367,18 +366,16 @@ STRONG_GLENUM_BEGIN(TexInternalFormat)
     STRONG_GLENUM_VALUE(COMPRESSED_RGBA_PVRTC_4BPPV1),
     STRONG_GLENUM_VALUE(COMPRESSED_RGBA_PVRTC_2BPPV1),
     STRONG_GLENUM_VALUE(R11F_G11F_B10F),
     STRONG_GLENUM_VALUE(RGB9_E5),
     STRONG_GLENUM_VALUE(SRGB),
     STRONG_GLENUM_VALUE(SRGB8),
     STRONG_GLENUM_VALUE(SRGB_ALPHA),
     STRONG_GLENUM_VALUE(SRGB8_ALPHA8),
-    STRONG_GLENUM_VALUE(ATC_RGB),
-    STRONG_GLENUM_VALUE(ATC_RGBA_EXPLICIT_ALPHA),
     STRONG_GLENUM_VALUE(DEPTH_COMPONENT32F),
     STRONG_GLENUM_VALUE(DEPTH32F_STENCIL8),
     STRONG_GLENUM_VALUE(RGB565),
     STRONG_GLENUM_VALUE(ETC1_RGB8_OES),
     STRONG_GLENUM_VALUE(RGBA32UI),
     STRONG_GLENUM_VALUE(RGB32UI),
     STRONG_GLENUM_VALUE(RGBA16UI),
     STRONG_GLENUM_VALUE(RGB16UI),
--- a/dom/canvas/WebGLTexture.cpp
+++ b/dom/canvas/WebGLTexture.cpp
@@ -10,16 +10,17 @@
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
 #include "mozilla/gfx/Logging.h"
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/Scoped.h"
 #include "mozilla/Unused.h"
 #include "ScopedGLHelpers.h"
 #include "WebGLContext.h"
 #include "WebGLContextUtils.h"
+#include "WebGLFormats.h"
 #include "WebGLFramebuffer.h"
 #include "WebGLSampler.h"
 #include "WebGLTexelConversions.h"
 
 namespace mozilla {
 
 /*static*/ const WebGLTexture::ImageInfo WebGLTexture::ImageInfo::kUndefined;
 
--- a/dom/canvas/WebGLTextureUpload.cpp
+++ b/dom/canvas/WebGLTextureUpload.cpp
@@ -997,88 +997,63 @@ ValidateCompressedTexImageRestrictions(W
                                          " or 2.",
                                          format->name);
             return false;
         }
 
         break;
 
     // Default: There are no restrictions on CompressedTexImage.
-    default: // ATC, ETC1, ES3
+    default: // ETC1, ES3
         break;
     }
 
     return true;
 }
 
 static bool
 ValidateTargetForFormat(WebGLContext* webgl, TexImageTarget target,
                         const webgl::FormatInfo* format)
 {
     // GLES 3.0.4 p127:
     // "Textures with a base internal format of DEPTH_COMPONENT or DEPTH_STENCIL are
     //  supported by texture image specification commands only if `target` is TEXTURE_2D,
     //  TEXTURE_2D_ARRAY, or TEXTURE_CUBE_MAP. Using these formats in conjunction with any
     //  other `target` will result in an INVALID_OPERATION error."
+    const bool ok = [&]() {
+        if (bool(format->d) & (target == LOCAL_GL_TEXTURE_3D))
+            return false;
 
-    switch (format->effectiveFormat) {
-    // TEXTURE_2D_ARRAY but not TEXTURE_3D:
-    // D and DS formats
-    case webgl::EffectiveFormat::DEPTH_COMPONENT16:
-    case webgl::EffectiveFormat::DEPTH_COMPONENT24:
-    case webgl::EffectiveFormat::DEPTH_COMPONENT32F:
-    case webgl::EffectiveFormat::DEPTH24_STENCIL8:
-    case webgl::EffectiveFormat::DEPTH32F_STENCIL8:
-    // CompressionFamily::ES3
-    case webgl::EffectiveFormat::COMPRESSED_R11_EAC:
-    case webgl::EffectiveFormat::COMPRESSED_SIGNED_R11_EAC:
-    case webgl::EffectiveFormat::COMPRESSED_RG11_EAC:
-    case webgl::EffectiveFormat::COMPRESSED_SIGNED_RG11_EAC:
-    case webgl::EffectiveFormat::COMPRESSED_RGB8_ETC2:
-    case webgl::EffectiveFormat::COMPRESSED_SRGB8_ETC2:
-    case webgl::EffectiveFormat::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
-    case webgl::EffectiveFormat::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
-    case webgl::EffectiveFormat::COMPRESSED_RGBA8_ETC2_EAC:
-    case webgl::EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
-    // CompressionFamily::S3TC
-    case webgl::EffectiveFormat::COMPRESSED_RGB_S3TC_DXT1_EXT:
-    case webgl::EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT1_EXT:
-    case webgl::EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT3_EXT:
-    case webgl::EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT5_EXT:
-        if (target == LOCAL_GL_TEXTURE_3D) {
-            webgl->ErrorInvalidOperation("Format %s cannot be used with TEXTURE_3D.",
-                                         format->name);
-            return false;
+        if (format->compression) {
+            switch (format->compression->family) {
+            case webgl::CompressionFamily::ES3:
+            case webgl::CompressionFamily::S3TC:
+                if (target == LOCAL_GL_TEXTURE_3D)
+                    return false;
+                break;
+
+            case webgl::CompressionFamily::ETC1:
+            case webgl::CompressionFamily::PVRTC:
+            case webgl::CompressionFamily::RGTC:
+                if (target == LOCAL_GL_TEXTURE_3D ||
+                    target == LOCAL_GL_TEXTURE_2D_ARRAY)
+                {
+                    return false;
+                }
+                break;
+            default:
+                break;
+            }
         }
-        break;
-
-    // No 3D targets:
-    // CompressionFamily::ATC
-    case webgl::EffectiveFormat::ATC_RGB_AMD:
-    case webgl::EffectiveFormat::ATC_RGBA_EXPLICIT_ALPHA_AMD:
-    case webgl::EffectiveFormat::ATC_RGBA_INTERPOLATED_ALPHA_AMD:
-    // CompressionFamily::PVRTC
-    case webgl::EffectiveFormat::COMPRESSED_RGB_PVRTC_4BPPV1:
-    case webgl::EffectiveFormat::COMPRESSED_RGBA_PVRTC_4BPPV1:
-    case webgl::EffectiveFormat::COMPRESSED_RGB_PVRTC_2BPPV1:
-    case webgl::EffectiveFormat::COMPRESSED_RGBA_PVRTC_2BPPV1:
-    // CompressionFamily::ETC1
-    case webgl::EffectiveFormat::ETC1_RGB8_OES:
-        if (target == LOCAL_GL_TEXTURE_3D ||
-            target == LOCAL_GL_TEXTURE_2D_ARRAY)
-        {
-            webgl->ErrorInvalidOperation("Format %s cannot be used with TEXTURE_3D or"
-                                         " TEXTURE_2D_ARRAY.",
-                                         format->name);
-            return false;
-        }
-        break;
-
-    default:
-        break;
+        return true;
+    }();
+    if (!ok) {
+        webgl->ErrorInvalidOperation("Format %s cannot be used with target %s.",
+                                     format->name, GetEnumName(target.get()));
+        return false;
     }
 
     return true;
 }
 
 void
 WebGLTexture::TexStorage(TexTarget target, GLsizei levels,
                          GLenum sizedFormat, GLsizei width, GLsizei height, GLsizei depth)
@@ -1585,24 +1560,25 @@ WebGLTexture::CompressedTexSubImage(TexI
     }
 
     ////////////////////////////////////
     // Check that source is compatible with dest
 
     switch (format->compression->family) {
     // Forbidden:
     case webgl::CompressionFamily::ETC1:
-    case webgl::CompressionFamily::ATC:
         mContext->ErrorInvalidOperation("Format does not allow sub-image"
                                         " updates.");
         return;
 
     // Block-aligned:
     case webgl::CompressionFamily::ES3:  // Yes, the ES3 formats don't match the ES3
     case webgl::CompressionFamily::S3TC: // default behavior.
+    case webgl::CompressionFamily::BPTC:
+    case webgl::CompressionFamily::RGTC:
         if (!IsSubImageBlockAligned(dstFormat->compression, imageInfo, xOffset, yOffset,
                                     blob->mWidth, blob->mHeight))
         {
             mContext->ErrorInvalidOperation("Format requires block-aligned sub-image"
                                             " updates.");
             return;
         }
         break;
--- a/dom/canvas/WebGLTypes.h
+++ b/dom/canvas/WebGLTypes.h
@@ -139,32 +139,33 @@ enum class WebGLTexDimensions : uint8_t 
 };
 
 // Please keep extensions in alphabetic order.
 enum class WebGLExtensionID : uint8_t {
     ANGLE_instanced_arrays,
     EXT_blend_minmax,
     EXT_color_buffer_float,
     EXT_color_buffer_half_float,
+    EXT_texture_compression_bptc,
+    EXT_texture_compression_rgtc,
     EXT_frag_depth,
     EXT_sRGB,
     EXT_shader_texture_lod,
     EXT_texture_filter_anisotropic,
     EXT_disjoint_timer_query,
     MOZ_debug,
     OES_element_index_uint,
     OES_standard_derivatives,
     OES_texture_float,
     OES_texture_float_linear,
     OES_texture_half_float,
     OES_texture_half_float_linear,
     OES_vertex_array_object,
     WEBGL_color_buffer_float,
     WEBGL_compressed_texture_astc,
-    WEBGL_compressed_texture_atc,
     WEBGL_compressed_texture_etc,
     WEBGL_compressed_texture_etc1,
     WEBGL_compressed_texture_pvrtc,
     WEBGL_compressed_texture_s3tc,
     WEBGL_compressed_texture_s3tc_srgb,
     WEBGL_debug_renderer_info,
     WEBGL_debug_shaders,
     WEBGL_depth_texture,
--- a/dom/canvas/moz.build
+++ b/dom/canvas/moz.build
@@ -120,20 +120,21 @@ UNIFIED_SOURCES += [
     'WebGLContextValidate.cpp',
     'WebGLContextVertexArray.cpp',
     'WebGLContextVertices.cpp',
     'WebGLExtensionBase.cpp',
     'WebGLExtensionBlendMinMax.cpp',
     'WebGLExtensionColorBufferFloat.cpp',
     'WebGLExtensionColorBufferHalfFloat.cpp',
     'WebGLExtensionCompressedTextureASTC.cpp',
-    'WebGLExtensionCompressedTextureATC.cpp',
+    'WebGLExtensionCompressedTextureBPTC.cpp',
     'WebGLExtensionCompressedTextureES3.cpp',
     'WebGLExtensionCompressedTextureETC1.cpp',
     'WebGLExtensionCompressedTexturePVRTC.cpp',
+    'WebGLExtensionCompressedTextureRGTC.cpp',
     'WebGLExtensionCompressedTextureS3TC.cpp',
     'WebGLExtensionCompressedTextureS3TC_SRGB.cpp',
     'WebGLExtensionDebugRendererInfo.cpp',
     'WebGLExtensionDebugShaders.cpp',
     'WebGLExtensionDepthTexture.cpp',
     'WebGLExtensionDisjointTimerQuery.cpp',
     'WebGLExtensionDrawBuffers.cpp',
     'WebGLExtensionElementIndexUint.cpp',
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/webgl-mochitest/ensure-exts/test_EXT_texture_compression_bptc.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<html>
+  <head>
+    <meta charset='utf-8'/>
+    <script src='/tests/SimpleTest/SimpleTest.js'></script>
+    <link rel='stylesheet' href='/tests/SimpleTest/test.css'>
+    <script src='ensure-ext.js'></script>
+  </head>
+  <body>
+    <script>
+
+'use strict';
+EnsureExt('EXT_texture_compression_bptc', false);
+
+Lastly_WithDraftExtsEnabled(() => {
+  EnsureExt('EXT_texture_compression_bptc', true);
+});
+    </script>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/webgl-mochitest/ensure-exts/test_EXT_texture_compression_rgtc.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML>
+<html>
+  <head>
+    <meta charset='utf-8'/>
+    <script src='/tests/SimpleTest/SimpleTest.js'></script>
+    <link rel='stylesheet' href='/tests/SimpleTest/test.css'>
+    <script src='ensure-ext.js'></script>
+  </head>
+  <body>
+    <script>
+
+'use strict';
+EnsureExt('EXT_texture_compression_rgtc', false);
+
+Lastly_WithDraftExtsEnabled(() => {
+  EnsureExt('EXT_texture_compression_rgtc', true);
+});
+
+    </script>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/webgl-mochitest/ensure-exts/test_WEBGL_compressed_texture_astc.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML>
+<html>
+  <head>
+    <meta charset='utf-8'/>
+    <script src='/tests/SimpleTest/SimpleTest.js'></script>
+    <link rel='stylesheet' href='/tests/SimpleTest/test.css'>
+    <script src='ensure-ext.js'></script>
+  </head>
+  <body>
+    <script>
+
+'use strict';
+EnsureExt('WEBGL_compressed_texture_astc');
+
+    </script>
+  </body>
+</html>
deleted file mode 100644
--- a/dom/canvas/test/webgl-mochitest/ensure-exts/test_WEBGL_compressed_texture_atc.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-  <head>
-    <meta charset='utf-8'/>
-    <script src='/tests/SimpleTest/SimpleTest.js'></script>
-    <link rel='stylesheet' href='/tests/SimpleTest/test.css'>
-    <script src='ensure-ext.js'></script>
-  </head>
-  <body>
-    <script>
-
-'use strict';
-EnsureExt('WEBGL_compressed_texture_atc');
-
-    </script>
-  </body>
-</html>
rename from dom/canvas/test/webgl-mochitest/ensure-exts/test_WEBGL_compressed_texture_es3.html
rename to dom/canvas/test/webgl-mochitest/ensure-exts/test_WEBGL_compressed_texture_etc.html
--- a/dom/canvas/test/webgl-mochitest/ensure-exts/test_common.html
+++ b/dom/canvas/test/webgl-mochitest/ensure-exts/test_common.html
@@ -14,17 +14,16 @@
 var ENSURE = 'ENSURE'; // Works on all test machines.
 var FORBID = 'FORBID'; // Should not work on any test machine.
 var MACHINE_SPECIFIC = 'MACHINE_SPECIFIC';
 
 var defaultExts = [
     // Ratified
     ['ANGLE_instanced_arrays'        , [MACHINE_SPECIFIC, FORBID          ]],
     ['EXT_blend_minmax'              , [MACHINE_SPECIFIC, FORBID          ]],
-    ['EXT_disjoint_timer_query'      , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
     ['EXT_frag_depth'                , [MACHINE_SPECIFIC, FORBID          ]],
     ['EXT_shader_texture_lod'        , [MACHINE_SPECIFIC, FORBID          ]],
     ['EXT_texture_filter_anisotropic', [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
     ['OES_element_index_uint'        , [ENSURE          , FORBID          ]],
     ['OES_standard_derivatives'      , [MACHINE_SPECIFIC, FORBID          ]],
     ['OES_texture_float'             , [ENSURE          , FORBID          ]],
     ['OES_texture_float_linear'      , [ENSURE          , ENSURE          ]],
     ['OES_texture_half_float'        , [ENSURE          , FORBID          ]],
@@ -33,32 +32,36 @@ var defaultExts = [
     ['WEBGL_compressed_texture_s3tc' , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
     ['WEBGL_debug_renderer_info'     , [ENSURE          , ENSURE          ]],
     ['WEBGL_debug_shaders'           , [ENSURE          , ENSURE          ]],
     ['WEBGL_depth_texture'           , [MACHINE_SPECIFIC, FORBID          ]],
     ['WEBGL_draw_buffers'            , [MACHINE_SPECIFIC, FORBID          ]],
     ['WEBGL_lose_context'            , [ENSURE          , ENSURE          ]],
 
     // Community Approved
-    ['EXT_color_buffer_float'        , [FORBID          , ENSURE          ]],
-    ['EXT_color_buffer_half_float'   , [MACHINE_SPECIFIC, FORBID          ]],
-    ['EXT_sRGB'                      , [MACHINE_SPECIFIC, FORBID          ]],
-    ['WEBGL_color_buffer_float'      , [MACHINE_SPECIFIC, FORBID          ]],
-    ['WEBGL_compressed_texture_atc'  , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
-    ['WEBGL_compressed_texture_etc1' , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
-    ['WEBGL_compressed_texture_pvrtc', [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
+    ['EXT_color_buffer_float'            , [FORBID          , ENSURE          ]],
+    ['EXT_color_buffer_half_float'       , [MACHINE_SPECIFIC, FORBID          ]],
+    ['EXT_disjoint_timer_query'          , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
+    ['EXT_sRGB'                          , [MACHINE_SPECIFIC, FORBID          ]],
+    ['WEBGL_color_buffer_float'          , [MACHINE_SPECIFIC, FORBID          ]],
+    ['WEBGL_compressed_texture_astc'     , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
+    ['WEBGL_compressed_texture_atc'      , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
+    ['WEBGL_compressed_texture_etc'      , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
+    ['WEBGL_compressed_texture_etc1'     , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
+    ['WEBGL_compressed_texture_pvrtc'    , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
+    ['WEBGL_compressed_texture_s3tc_srgb', [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
 ];
 
 var draftExts = [
-    ['WEBGL_compressed_texture_es3', [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
+    ['EXT_texture_compression_bptc', [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
+    ['EXT_texture_compression_rgtc', [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
 ];
 
 var nonImplementedExts = [
     'OES_fbo_render_mipmap',
-    'WEBGL_compressed_texture_astc',
     'WEBGL_security_sensitive_resources',
     'WEBGL_shared_resources',
 ];
 
 ////////////////////
 
 function TestExtFor(contextType, extName, status) {
     switch (status) {
--- a/dom/canvas/test/webgl-mochitest/mochitest.ini
+++ b/dom/canvas/test/webgl-mochitest/mochitest.ini
@@ -21,25 +21,29 @@ fail-if = (os == 'android')
 [ensure-exts/test_EXT_disjoint_timer_query.html]
 fail-if = 1
 [ensure-exts/test_EXT_frag_depth.html]
 fail-if = (os == 'android')
 [ensure-exts/test_EXT_sRGB.html]
 fail-if = (os == 'android')
 [ensure-exts/test_EXT_shader_texture_lod.html]
 fail-if = (os == 'android')
+[ensure-exts/test_EXT_texture_compression_bptc.html]
+fail-if = (os == 'android') || (os == 'linux') || (os == 'mac') || (os == 'win')
+[ensure-exts/test_EXT_texture_compression_rgtc.html]
+fail-if = (os == 'android') || (os == 'win')
 [ensure-exts/test_EXT_texture_filter_anisotropic.html]
 fail-if = (os == 'android') || (os == 'linux')
 [ensure-exts/test_OES_standard_derivatives.html]
 fail-if = (os == 'android')
 [ensure-exts/test_WEBGL_color_buffer_float.html]
 fail-if = (os == 'android')
-[ensure-exts/test_WEBGL_compressed_texture_atc.html]
+[ensure-exts/test_WEBGL_compressed_texture_astc.html]
 fail-if = (os == 'android') || (os == 'linux') || (os == 'mac') || (os == 'win')
-[ensure-exts/test_WEBGL_compressed_texture_es3.html]
+[ensure-exts/test_WEBGL_compressed_texture_etc.html]
 fail-if = (os == 'android') || (os == 'mac') || (os == 'win')
 [ensure-exts/test_WEBGL_compressed_texture_etc1.html]
 fail-if = (os == 'linux') || (os == 'mac') || (os == 'win')
 [ensure-exts/test_WEBGL_compressed_texture_pvrtc.html]
 fail-if = (os == 'android') || (os == 'linux') || (os == 'mac') || (os == 'win')
 [ensure-exts/test_WEBGL_compressed_texture_s3tc.html]
 fail-if = (os == 'android')
 [ensure-exts/test_WEBGL_depth_texture.html]
--- a/dom/canvas/test/webgl-mochitest/test_webgl_compressed_texture_es3.html
+++ b/dom/canvas/test/webgl-mochitest/test_webgl_compressed_texture_es3.html
@@ -1,17 +1,17 @@
 <!DOCTYPE html>
 <html>
 <head>
 <meta charset="utf-8">
 <script src="/tests/SimpleTest/SimpleTest.js"></script>
 <link rel="stylesheet" href="/tests/SimpleTest/test.css">
 <script src="webgl-util.js"></script>
 <script src="es3-data.js"></script>
-<title>WebGL test: test WEBGL_compressed_texture_es3 extension</title>
+<title>WebGL test: test WEBGL_compressed_texture_etc extension</title>
 <style>
 img {
  border: 1px solid black;
  margin-right: 1em;
 }
 .testimages {
 }
 
@@ -119,43 +119,43 @@ function runTest() {
     } else {
         ok(true, "WebGL context exists");
         setupUnitQuad();
 
         // Run tests with extension disabled
         runTestDisabled();
 
         // Query the extension and store globally so shouldBe can access it
-        ext = gl.getExtension("WEBGL_compressed_texture_es3");
+        ext = gl.getExtension("WEBGL_compressed_texture_etc");
         if (!ext) {
-            ok(true, "No WEBGL_compressed_texture_es3 support -- this is legal");
+            ok(true, "No WEBGL_compressed_texture_etc support -- this is legal");
             runSupportedTest(false);
         } else {
-            ok(true, "Successfully enabled WEBGL_compressed_texture_es3 extension");
+            ok(true, "Successfully enabled WEBGL_compressed_texture_etc extension");
 
             runSupportedTest(true);
             runTestExtension();
         }
     }
     SimpleTest.finish();
 }
 
 function runSupportedTest(extensionEnabled) {
     var supported = gl.getSupportedExtensions();
-    if (supported.includes("WEBGL_compressed_texture_es3")) {
+    if (supported.includes("WEBGL_compressed_texture_etc")) {
         if (extensionEnabled) {
-            ok(true, "WEBGL_compressed_texture_es3 listed as supported and getExtension succeeded");
+            ok(true, "WEBGL_compressed_texture_etc listed as supported and getExtension succeeded");
         } else {
-            ok(false, "WEBGL_compressed_texture_es3 listed as supported but getExtension failed");
+            ok(false, "WEBGL_compressed_texture_etc listed as supported but getExtension failed");
         }
     } else {
         if (extensionEnabled) {
-            ok(false, "WEBGL_compressed_texture_es3 not listed as supported but getExtension succeeded");
+            ok(false, "WEBGL_compressed_texture_etc not listed as supported but getExtension succeeded");
         } else {
-            ok(true, "WEBGL_compressed_texture_es3 not listed as supported and getExtension failed -- this is legal");
+            ok(true, "WEBGL_compressed_texture_etc not listed as supported and getExtension failed -- this is legal");
         }
     }
 }
 
 function runTestDisabled() {
     is(gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS).length, 0,
        "Should be no compressed texture formats");
 }
--- a/dom/webidl/WebGLRenderingContext.webidl
+++ b/dom/webidl/WebGLRenderingContext.webidl
@@ -811,16 +811,32 @@ partial interface WebGLRenderingContext 
     [Func="mozilla::dom::DOMPrefs::gfx_offscreencanvas_enabled"]
     void commit();
 };
 
 ////////////////////////////////////////
 // specific extension interfaces
 
 [NoInterfaceObject]
+interface EXT_texture_compression_bptc {
+    const GLenum COMPRESSED_RGBA_BPTC_UNORM_EXT = 0x8E8C;
+    const GLenum COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT = 0x8E8D;
+    const GLenum COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT = 0x8E8E;
+    const GLenum COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT = 0x8E8F;
+};
+
+[NoInterfaceObject]
+interface EXT_texture_compression_rgtc {
+    const GLenum COMPRESSED_RED_RGTC1_EXT = 0x8DBB;
+    const GLenum COMPRESSED_SIGNED_RED_RGTC1_EXT = 0x8DBC;
+    const GLenum COMPRESSED_RED_GREEN_RGTC2_EXT = 0x8DBD;
+    const GLenum COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT = 0x8DBE;
+};
+
+[NoInterfaceObject]
 interface WEBGL_compressed_texture_s3tc
 {
     const GLenum COMPRESSED_RGB_S3TC_DXT1_EXT  = 0x83F0;
     const GLenum COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1;
     const GLenum COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2;
     const GLenum COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3;
 };
 
@@ -866,24 +882,16 @@ interface WEBGL_compressed_texture_astc 
     const GLenum COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR = 0x93DC;
     const GLenum COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR = 0x93DD;
 
     // Profile query support.
     sequence<DOMString>? getSupportedProfiles();
 };
 
 [NoInterfaceObject]
-interface WEBGL_compressed_texture_atc
-{
-    const GLenum COMPRESSED_RGB_ATC_WEBGL                     = 0x8C92;
-    const GLenum COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL     = 0x8C93;
-    const GLenum COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL = 0x87EE;
-};
-
-[NoInterfaceObject]
 interface WEBGL_compressed_texture_etc
 {
     const GLenum COMPRESSED_R11_EAC                                 = 0x9270;
     const GLenum COMPRESSED_SIGNED_R11_EAC                          = 0x9271;
     const GLenum COMPRESSED_RG11_EAC                                = 0x9272;
     const GLenum COMPRESSED_SIGNED_RG11_EAC                         = 0x9273;
     const GLenum COMPRESSED_RGB8_ETC2                               = 0x9274;
     const GLenum COMPRESSED_SRGB8_ETC2                              = 0x9275;
--- a/gfx/gl/GLConsts.h
+++ b/gfx/gl/GLConsts.h
@@ -188,21 +188,25 @@
 #define LOCAL_GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS        0x92C5
 #define LOCAL_GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6
 #define LOCAL_GL_ATOMIC_COUNTER_BUFFER_BINDING               0x92C1
 #define LOCAL_GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE             0x92C4
 #define LOCAL_GL_ATOMIC_COUNTER_BUFFER_INDEX                 0x9301
 #define LOCAL_GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER  0x90ED
 #define LOCAL_GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB
 #define LOCAL_GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA
+#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_MESH_SHADER_NV  0x959E
+#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TASK_SHADER_NV  0x959F
 #define LOCAL_GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER     0x92C8
 #define LOCAL_GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER  0x92C9
 #define LOCAL_GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER   0x92C7
 #define LOCAL_GL_ATOMIC_COUNTER_BUFFER_SIZE                  0x92C3
 #define LOCAL_GL_ATOMIC_COUNTER_BUFFER_START                 0x92C2
+#define LOCAL_GL_ATTACHED_MEMORY_OBJECT_NV                   0x95A4
+#define LOCAL_GL_ATTACHED_MEMORY_OFFSET_NV                   0x95A5
 #define LOCAL_GL_ATTACHED_SHADERS                            0x8B85
 #define LOCAL_GL_ATTENUATION_EXT                             0x834D
 #define LOCAL_GL_ATTRIBUTE_ADDRESS_COMMAND_NV                0x0009
 #define LOCAL_GL_ATTRIB_ARRAY_POINTER_NV                     0x8645
 #define LOCAL_GL_ATTRIB_ARRAY_SIZE_NV                        0x8623
 #define LOCAL_GL_ATTRIB_ARRAY_STRIDE_NV                      0x8624
 #define LOCAL_GL_ATTRIB_ARRAY_TYPE_NV                        0x8625
 #define LOCAL_GL_ATTRIB_STACK_DEPTH                          0x0BB0
@@ -237,16 +241,17 @@
 #define LOCAL_GL_BIAS_BY_NEGATIVE_ONE_HALF_NV                0x8541
 #define LOCAL_GL_BINNING_CONTROL_HINT_QCOM                   0x8FB0
 #define LOCAL_GL_BINORMAL_ARRAY_EXT                          0x843A
 #define LOCAL_GL_BINORMAL_ARRAY_POINTER_EXT                  0x8443
 #define LOCAL_GL_BINORMAL_ARRAY_STRIDE_EXT                   0x8441
 #define LOCAL_GL_BINORMAL_ARRAY_TYPE_EXT                     0x8440
 #define LOCAL_GL_BITMAP                                      0x1A00
 #define LOCAL_GL_BITMAP_TOKEN                                0x0704
+#define LOCAL_GL_BLACKHOLE_RENDER_INTEL                      0x83FC
 #define LOCAL_GL_BLEND                                       0x0BE2
 #define LOCAL_GL_BLEND_ADVANCED_COHERENT_KHR                 0x9285
 #define LOCAL_GL_BLEND_ADVANCED_COHERENT_NV                  0x9285
 #define LOCAL_GL_BLEND_COLOR                                 0x8005
 #define LOCAL_GL_BLEND_COLOR_COMMAND_NV                      0x000B
 #define LOCAL_GL_BLEND_COLOR_EXT                             0x8005
 #define LOCAL_GL_BLEND_DST                                   0x0BE0
 #define LOCAL_GL_BLEND_DST_ALPHA                             0x80CA
@@ -368,19 +373,22 @@
 #define LOCAL_GL_CLIENT_ALL_ATTRIB_BITS                      0xFFFFFFFF
 #define LOCAL_GL_CLIENT_ATTRIB_STACK_DEPTH                   0x0BB1
 #define LOCAL_GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT            0x00004000
 #define LOCAL_GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT        0x00004000
 #define LOCAL_GL_CLIENT_PIXEL_STORE_BIT                      0x00000001
 #define LOCAL_GL_CLIENT_STORAGE_BIT                          0x0200
 #define LOCAL_GL_CLIENT_STORAGE_BIT_EXT                      0x0200
 #define LOCAL_GL_CLIENT_VERTEX_ARRAY_BIT                     0x00000002
+#define LOCAL_GL_CLIPPING_INPUT_PRIMITIVES                   0x82F6
 #define LOCAL_GL_CLIPPING_INPUT_PRIMITIVES_ARB               0x82F6
+#define LOCAL_GL_CLIPPING_OUTPUT_PRIMITIVES                  0x82F7
 #define LOCAL_GL_CLIPPING_OUTPUT_PRIMITIVES_ARB              0x82F7
 #define LOCAL_GL_CLIP_DEPTH_MODE                             0x935D
+#define LOCAL_GL_CLIP_DEPTH_MODE_EXT                         0x935D
 #define LOCAL_GL_CLIP_DISTANCE0                              0x3000
 #define LOCAL_GL_CLIP_DISTANCE0_APPLE                        0x3000
 #define LOCAL_GL_CLIP_DISTANCE0_EXT                          0x3000
 #define LOCAL_GL_CLIP_DISTANCE1                              0x3001
 #define LOCAL_GL_CLIP_DISTANCE1_APPLE                        0x3001
 #define LOCAL_GL_CLIP_DISTANCE1_EXT                          0x3001
 #define LOCAL_GL_CLIP_DISTANCE2                              0x3002
 #define LOCAL_GL_CLIP_DISTANCE2_APPLE                        0x3002
@@ -399,16 +407,17 @@
 #define LOCAL_GL_CLIP_DISTANCE6_EXT                          0x3006
 #define LOCAL_GL_CLIP_DISTANCE7                              0x3007
 #define LOCAL_GL_CLIP_DISTANCE7_APPLE                        0x3007
 #define LOCAL_GL_CLIP_DISTANCE7_EXT                          0x3007
 #define LOCAL_GL_CLIP_DISTANCE_NV                            0x8C7A
 #define LOCAL_GL_CLIP_FAR_HINT_PGI                           0x1A221
 #define LOCAL_GL_CLIP_NEAR_HINT_PGI                          0x1A220
 #define LOCAL_GL_CLIP_ORIGIN                                 0x935C
+#define LOCAL_GL_CLIP_ORIGIN_EXT                             0x935C
 #define LOCAL_GL_CLIP_PLANE0                                 0x3000
 #define LOCAL_GL_CLIP_PLANE0_IMG                             0x3000
 #define LOCAL_GL_CLIP_PLANE1                                 0x3001
 #define LOCAL_GL_CLIP_PLANE1_IMG                             0x3001
 #define LOCAL_GL_CLIP_PLANE2                                 0x3002
 #define LOCAL_GL_CLIP_PLANE2_IMG                             0x3002
 #define LOCAL_GL_CLIP_PLANE3                                 0x3003
 #define LOCAL_GL_CLIP_PLANE3_IMG                             0x3003
@@ -613,16 +622,17 @@
 #define LOCAL_GL_COMPARE_REF_TO_TEXTURE_EXT                  0x884E
 #define LOCAL_GL_COMPARE_R_TO_TEXTURE                        0x884E
 #define LOCAL_GL_COMPARE_R_TO_TEXTURE_ARB                    0x884E
 #define LOCAL_GL_COMPATIBLE_SUBROUTINES                      0x8E4B
 #define LOCAL_GL_COMPILE                                     0x1300
 #define LOCAL_GL_COMPILE_AND_EXECUTE                         0x1301
 #define LOCAL_GL_COMPILE_STATUS                              0x8B81
 #define LOCAL_GL_COMPLETION_STATUS_ARB                       0x91B1
+#define LOCAL_GL_COMPLETION_STATUS_KHR                       0x91B1
 #define LOCAL_GL_COMPRESSED_ALPHA                            0x84E9
 #define LOCAL_GL_COMPRESSED_ALPHA_ARB                        0x84E9
 #define LOCAL_GL_COMPRESSED_INTENSITY                        0x84EC
 #define LOCAL_GL_COMPRESSED_INTENSITY_ARB                    0x84EC
 #define LOCAL_GL_COMPRESSED_LUMINANCE                        0x84EA
 #define LOCAL_GL_COMPRESSED_LUMINANCE_ALPHA                  0x84EB
 #define LOCAL_GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI          0x8837
 #define LOCAL_GL_COMPRESSED_LUMINANCE_ALPHA_ARB              0x84EB
@@ -682,31 +692,34 @@
 #define LOCAL_GL_COMPRESSED_RGBA_ASTC_8x5                    0x93B5
 #define LOCAL_GL_COMPRESSED_RGBA_ASTC_8x5_KHR                0x93B5
 #define LOCAL_GL_COMPRESSED_RGBA_ASTC_8x6                    0x93B6
 #define LOCAL_GL_COMPRESSED_RGBA_ASTC_8x6_KHR                0x93B6
 #define LOCAL_GL_COMPRESSED_RGBA_ASTC_8x8                    0x93B7
 #define LOCAL_GL_COMPRESSED_RGBA_ASTC_8x8_KHR                0x93B7
 #define LOCAL_GL_COMPRESSED_RGBA_BPTC_UNORM                  0x8E8C
 #define LOCAL_GL_COMPRESSED_RGBA_BPTC_UNORM_ARB              0x8E8C
+#define LOCAL_GL_COMPRESSED_RGBA_BPTC_UNORM_EXT              0x8E8C
 #define LOCAL_GL_COMPRESSED_RGBA_FXT1_3DFX                   0x86B1
 #define LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG            0x8C03
 #define LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG            0x9137
 #define LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG            0x8C02
 #define LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG            0x9138
 #define LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT               0x83F1
 #define LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE             0x83F2
 #define LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT               0x83F2
 #define LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE             0x83F3
 #define LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT               0x83F3
 #define LOCAL_GL_COMPRESSED_RGB_ARB                          0x84ED
 #define LOCAL_GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT            0x8E8E
 #define LOCAL_GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB        0x8E8E
+#define LOCAL_GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT        0x8E8E
 #define LOCAL_GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT          0x8E8F
 #define LOCAL_GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB      0x8E8F
+#define LOCAL_GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT      0x8E8F
 #define LOCAL_GL_COMPRESSED_RGB_FXT1_3DFX                    0x86B0
 #define LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG             0x8C01
 #define LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG             0x8C00
 #define LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT                0x83F0
 #define LOCAL_GL_COMPRESSED_RG_RGTC2                         0x8DBD
 #define LOCAL_GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73
 #define LOCAL_GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT       0x8C71
 #define LOCAL_GL_COMPRESSED_SIGNED_R11_EAC                   0x9271
@@ -764,16 +777,17 @@
 #define LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_OES        0x9279
 #define LOCAL_GL_COMPRESSED_SRGB8_ETC2                       0x9275
 #define LOCAL_GL_COMPRESSED_SRGB8_ETC2_OES                   0x9275
 #define LOCAL_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2   0x9277
 #define LOCAL_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_OES       0x9277
 #define LOCAL_GL_COMPRESSED_SRGB_ALPHA                       0x8C49
 #define LOCAL_GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM            0x8E8D
 #define LOCAL_GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB        0x8E8D
+#define LOCAL_GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT        0x8E8D
 #define LOCAL_GL_COMPRESSED_SRGB_ALPHA_EXT                   0x8C49
 #define LOCAL_GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT      0x8A56
 #define LOCAL_GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG      0x93F0
 #define LOCAL_GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT      0x8A57
 #define LOCAL_GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG      0x93F1
 #define LOCAL_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT         0x8C4D
 #define LOCAL_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV          0x8C4D
 #define LOCAL_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT         0x8C4E
@@ -786,16 +800,17 @@
 #define LOCAL_GL_COMPRESSED_SRGB_S3TC_DXT1_EXT               0x8C4C
 #define LOCAL_GL_COMPRESSED_SRGB_S3TC_DXT1_NV                0x8C4C
 #define LOCAL_GL_COMPRESSED_TEXTURE_FORMATS                  0x86A3
 #define LOCAL_GL_COMPRESSED_TEXTURE_FORMATS_ARB              0x86A3
 #define LOCAL_GL_COMPUTE_PROGRAM_NV                          0x90FB
 #define LOCAL_GL_COMPUTE_PROGRAM_PARAMETER_BUFFER_NV         0x90FC
 #define LOCAL_GL_COMPUTE_SHADER                              0x91B9
 #define LOCAL_GL_COMPUTE_SHADER_BIT                          0x00000020
+#define LOCAL_GL_COMPUTE_SHADER_INVOCATIONS                  0x82F5
 #define LOCAL_GL_COMPUTE_SHADER_INVOCATIONS_ARB              0x82F5
 #define LOCAL_GL_COMPUTE_SUBROUTINE                          0x92ED
 #define LOCAL_GL_COMPUTE_SUBROUTINE_UNIFORM                  0x92F3
 #define LOCAL_GL_COMPUTE_TEXTURE                             0x82A0
 #define LOCAL_GL_COMPUTE_WORK_GROUP_SIZE                     0x8267
 #define LOCAL_GL_COMP_BIT_ATI                                0x00000002
 #define LOCAL_GL_CONDITION_SATISFIED                         0x911C
 #define LOCAL_GL_CONDITION_SATISFIED_APPLE                   0x911C
@@ -804,16 +819,17 @@
 #define LOCAL_GL_CONJOINT_NV                                 0x9284
 #define LOCAL_GL_CONSERVATIVE_RASTERIZATION_INTEL            0x83FE
 #define LOCAL_GL_CONSERVATIVE_RASTERIZATION_NV               0x9346
 #define LOCAL_GL_CONSERVATIVE_RASTER_DILATE_GRANULARITY_NV   0x937B
 #define LOCAL_GL_CONSERVATIVE_RASTER_DILATE_NV               0x9379
 #define LOCAL_GL_CONSERVATIVE_RASTER_DILATE_RANGE_NV         0x937A
 #define LOCAL_GL_CONSERVATIVE_RASTER_MODE_NV                 0x954D
 #define LOCAL_GL_CONSERVATIVE_RASTER_MODE_POST_SNAP_NV       0x954E
+#define LOCAL_GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_NV        0x9550
 #define LOCAL_GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_TRIANGLES_NV      0x954F
 #define LOCAL_GL_CONSERVE_MEMORY_HINT_PGI                    0x1A1FD
 #define LOCAL_GL_CONSTANT                                    0x8576
 #define LOCAL_GL_CONSTANT_ALPHA                              0x8003
 #define LOCAL_GL_CONSTANT_ALPHA_EXT                          0x8003
 #define LOCAL_GL_CONSTANT_ARB                                0x8576
 #define LOCAL_GL_CONSTANT_ATTENUATION                        0x1207
 #define LOCAL_GL_CONSTANT_BORDER                             0x8151
@@ -826,16 +842,17 @@
 #define LOCAL_GL_CONSTANT_NV                                 0x8576
 #define LOCAL_GL_CONST_EYE_NV                                0x86E5
 #define LOCAL_GL_CONTEXT_COMPATIBILITY_PROFILE_BIT           0x00000002
 #define LOCAL_GL_CONTEXT_CORE_PROFILE_BIT                    0x00000001
 #define LOCAL_GL_CONTEXT_FLAGS                               0x821E
 #define LOCAL_GL_CONTEXT_FLAG_DEBUG_BIT                      0x00000002
 #define LOCAL_GL_CONTEXT_FLAG_DEBUG_BIT_KHR                  0x00000002
 #define LOCAL_GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT         0x00000001
+#define LOCAL_GL_CONTEXT_FLAG_NO_ERROR_BIT                   0x00000008
 #define LOCAL_GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR               0x00000008
 #define LOCAL_GL_CONTEXT_FLAG_PROTECTED_CONTENT_BIT_EXT      0x00000010
 #define LOCAL_GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT              0x00000004
 #define LOCAL_GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB          0x00000004
 #define LOCAL_GL_CONTEXT_LOST                                0x0507
 #define LOCAL_GL_CONTEXT_LOST_KHR                            0x0507
 #define LOCAL_GL_CONTEXT_LOST_WEBGL                          0x9242
 #define LOCAL_GL_CONTEXT_PROFILE_MASK                        0x9126
@@ -1152,16 +1169,19 @@
 #define LOCAL_GL_DEPTH_STENCIL_OES                           0x84F9
 #define LOCAL_GL_DEPTH_STENCIL_TEXTURE_MODE                  0x90EA
 #define LOCAL_GL_DEPTH_STENCIL_TO_BGRA_NV                    0x886F
 #define LOCAL_GL_DEPTH_STENCIL_TO_RGBA_NV                    0x886E
 #define LOCAL_GL_DEPTH_TEST                                  0x0B71
 #define LOCAL_GL_DEPTH_TEXTURE_MODE                          0x884B
 #define LOCAL_GL_DEPTH_TEXTURE_MODE_ARB                      0x884B
 #define LOCAL_GL_DEPTH_WRITEMASK                             0x0B72
+#define LOCAL_GL_DETACHED_BUFFERS_NV                         0x95AB
+#define LOCAL_GL_DETACHED_MEMORY_INCARNATION_NV              0x95A9
+#define LOCAL_GL_DETACHED_TEXTURES_NV                        0x95AA
 #define LOCAL_GL_DETAIL_TEXTURE_2D_BINDING_SGIS              0x8096
 #define LOCAL_GL_DETAIL_TEXTURE_2D_SGIS                      0x8095
 #define LOCAL_GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS             0x809C
 #define LOCAL_GL_DETAIL_TEXTURE_LEVEL_SGIS                   0x809A
 #define LOCAL_GL_DETAIL_TEXTURE_MODE_SGIS                    0x809B
 #define LOCAL_GL_DEVICE_LUID_EXT                             0x9599
 #define LOCAL_GL_DEVICE_NODE_MASK_EXT                        0x959A
 #define LOCAL_GL_DEVICE_UUID_EXT                             0x9597
@@ -1450,16 +1470,17 @@
 #define LOCAL_GL_EXCLUSION_KHR                               0x92A0
 #define LOCAL_GL_EXCLUSION_NV                                0x92A0
 #define LOCAL_GL_EXCLUSIVE_EXT                               0x8F11
 #define LOCAL_GL_EXP                                         0x0800
 #define LOCAL_GL_EXP2                                        0x0801
 #define LOCAL_GL_EXPAND_NEGATE_NV                            0x8539
 #define LOCAL_GL_EXPAND_NORMAL_NV                            0x8538
 #define LOCAL_GL_EXTENSIONS                                  0x1F03
+#define LOCAL_GL_EXTERNAL_STORAGE_BIT_NVX                    0x2000
 #define LOCAL_GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD          0x9160
 #define LOCAL_GL_EYE_DISTANCE_TO_LINE_SGIS                   0x81F2
 #define LOCAL_GL_EYE_DISTANCE_TO_POINT_SGIS                  0x81F0
 #define LOCAL_GL_EYE_LINEAR                                  0x2400
 #define LOCAL_GL_EYE_LINEAR_NV                               0x2400
 #define LOCAL_GL_EYE_LINE_SGIS                               0x81F6
 #define LOCAL_GL_EYE_PLANE                                   0x2502
 #define LOCAL_GL_EYE_PLANE_ABSOLUTE_NV                       0x855C
@@ -1610,16 +1631,17 @@
 #define LOCAL_GL_FONT_X_MIN_BOUNDS_BIT_NV                    0x00010000
 #define LOCAL_GL_FONT_Y_MAX_BOUNDS_BIT_NV                    0x00080000
 #define LOCAL_GL_FONT_Y_MIN_BOUNDS_BIT_NV                    0x00020000
 #define LOCAL_GL_FORCE_BLUE_TO_ONE_NV                        0x8860
 #define LOCAL_GL_FORMAT_SUBSAMPLE_244_244_OML                0x8983
 #define LOCAL_GL_FORMAT_SUBSAMPLE_24_24_OML                  0x8982
 #define LOCAL_GL_FOVEATION_ENABLE_BIT_QCOM                   0x00000001
 #define LOCAL_GL_FOVEATION_SCALED_BIN_METHOD_BIT_QCOM        0x00000002
+#define LOCAL_GL_FOVEATION_SUBSAMPLED_LAYOUT_METHOD_BIT_QCOM 0x00000004
 #define LOCAL_GL_FRACTIONAL_EVEN                             0x8E7C
 #define LOCAL_GL_FRACTIONAL_EVEN_EXT                         0x8E7C
 #define LOCAL_GL_FRACTIONAL_EVEN_OES                         0x8E7C
 #define LOCAL_GL_FRACTIONAL_ODD                              0x8E7B
 #define LOCAL_GL_FRACTIONAL_ODD_EXT                          0x8E7B
 #define LOCAL_GL_FRACTIONAL_ODD_OES                          0x8E7B
 #define LOCAL_GL_FRAGMENTS_INSTRUMENT_COUNTERS_SGIX          0x8314
 #define LOCAL_GL_FRAGMENTS_INSTRUMENT_MAX_SGIX               0x8315
@@ -1665,16 +1687,17 @@
 #define LOCAL_GL_FRAGMENT_SHADER_ATI                         0x8920
 #define LOCAL_GL_FRAGMENT_SHADER_BIT                         0x00000002
 #define LOCAL_GL_FRAGMENT_SHADER_BIT_EXT                     0x00000002
 #define LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT             0x8B8B
 #define LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB         0x8B8B
 #define LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES         0x8B8B
 #define LOCAL_GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT        0x8A52
 #define LOCAL_GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM   0x8F66
+#define LOCAL_GL_FRAGMENT_SHADER_INVOCATIONS                 0x82F4
 #define LOCAL_GL_FRAGMENT_SHADER_INVOCATIONS_ARB             0x82F4
 #define LOCAL_GL_FRAGMENT_SUBROUTINE                         0x92EC
 #define LOCAL_GL_FRAGMENT_SUBROUTINE_UNIFORM                 0x92F2
 #define LOCAL_GL_FRAGMENT_TEXTURE                            0x829F
 #define LOCAL_GL_FRAMEBUFFER                                 0x8D40
 #define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE           0x8215
 #define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_ANGLE                0x93A3
 #define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE            0x8214
@@ -1725,27 +1748,29 @@
 #define LOCAL_GL_FRAMEBUFFER_DEFAULT_HEIGHT                  0x9311
 #define LOCAL_GL_FRAMEBUFFER_DEFAULT_LAYERS                  0x9312
 #define LOCAL_GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT              0x9312
 #define LOCAL_GL_FRAMEBUFFER_DEFAULT_LAYERS_OES              0x9312
 #define LOCAL_GL_FRAMEBUFFER_DEFAULT_SAMPLES                 0x9313
 #define LOCAL_GL_FRAMEBUFFER_DEFAULT_WIDTH                   0x9310
 #define LOCAL_GL_FRAMEBUFFER_EXT                             0x8D40
 #define LOCAL_GL_FRAMEBUFFER_FETCH_NONCOHERENT_QCOM          0x96A2
+#define LOCAL_GL_FRAMEBUFFER_FLIP_Y_MESA                     0x8BBB
 #define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT           0x8CD6
 #define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT       0x8CD6
 #define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES       0x8CD6
 #define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS           0x8CD9
 #define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT       0x8CD9
 #define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES       0x8CD9
 #define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER          0x8CDB
 #define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT      0x8CDB
 #define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_OES      0x8CDB
 #define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT          0x8CDA
 #define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES          0x8CDA
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_FOVEATION_QCOM       0x8BFF
 #define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_INSUFFICIENT_SHADER_COMBINED_LOCAL_STORAGE_EXT       0x9652
 #define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB      0x8DA9
 #define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT      0x8DA9
 #define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS        0x8DA8
 #define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB    0x8DA8
 #define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT    0x8DA8
 #define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_OES    0x8DA8
 #define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT   0x8CD7
@@ -1825,16 +1850,17 @@
 #define LOCAL_GL_GEOMETRY_SHADER_BIT                         0x00000004
 #define LOCAL_GL_GEOMETRY_SHADER_BIT_EXT                     0x00000004
 #define LOCAL_GL_GEOMETRY_SHADER_BIT_OES                     0x00000004
 #define LOCAL_GL_GEOMETRY_SHADER_EXT                         0x8DD9
 #define LOCAL_GL_GEOMETRY_SHADER_INVOCATIONS                 0x887F
 #define LOCAL_GL_GEOMETRY_SHADER_INVOCATIONS_EXT             0x887F
 #define LOCAL_GL_GEOMETRY_SHADER_INVOCATIONS_OES             0x887F
 #define LOCAL_GL_GEOMETRY_SHADER_OES                         0x8DD9
+#define LOCAL_GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED          0x82F3
 #define LOCAL_GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB      0x82F3
 #define LOCAL_GL_GEOMETRY_SUBROUTINE                         0x92EB
 #define LOCAL_GL_GEOMETRY_SUBROUTINE_UNIFORM                 0x92F1
 #define LOCAL_GL_GEOMETRY_TEXTURE                            0x829E
 #define LOCAL_GL_GEOMETRY_VERTICES_OUT                       0x8916
 #define LOCAL_GL_GEOMETRY_VERTICES_OUT_ARB                   0x8DDA
 #define LOCAL_GL_GEOMETRY_VERTICES_OUT_EXT                   0x8DDA
 #define LOCAL_GL_GEQUAL                                      0x0206
@@ -2210,16 +2236,18 @@
 #define LOCAL_GL_LAST_VERTEX_CONVENTION_OES                  0x8E4E
 #define LOCAL_GL_LAST_VIDEO_CAPTURE_STATUS_NV                0x9027
 #define LOCAL_GL_LAYER_NV                                    0x8DAA
 #define LOCAL_GL_LAYER_PROVOKING_VERTEX                      0x825E
 #define LOCAL_GL_LAYER_PROVOKING_VERTEX_EXT                  0x825E
 #define LOCAL_GL_LAYER_PROVOKING_VERTEX_OES                  0x825E
 #define LOCAL_GL_LAYOUT_COLOR_ATTACHMENT_EXT                 0x958E
 #define LOCAL_GL_LAYOUT_DEFAULT_INTEL                        0
+#define LOCAL_GL_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_EXT       0x9531
+#define LOCAL_GL_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_EXT       0x9530
 #define LOCAL_GL_LAYOUT_DEPTH_STENCIL_ATTACHMENT_EXT         0x958F
 #define LOCAL_GL_LAYOUT_DEPTH_STENCIL_READ_ONLY_EXT          0x9590
 #define LOCAL_GL_LAYOUT_GENERAL_EXT                          0x958D
 #define LOCAL_GL_LAYOUT_LINEAR_CPU_CACHED_INTEL              2
 #define LOCAL_GL_LAYOUT_LINEAR_INTEL                         1
 #define LOCAL_GL_LAYOUT_SHADER_READ_ONLY_EXT                 0x9591
 #define LOCAL_GL_LAYOUT_TRANSFER_DST_EXT                     0x9593
 #define LOCAL_GL_LAYOUT_TRANSFER_SRC_EXT                     0x9592
@@ -2308,16 +2336,17 @@
 #define LOCAL_GL_LOCATION_INDEX_EXT                          0x930F
 #define LOCAL_GL_LOGIC_OP                                    0x0BF1
 #define LOCAL_GL_LOGIC_OP_MODE                               0x0BF0
 #define LOCAL_GL_LOSE_CONTEXT_ON_RESET                       0x8252
 #define LOCAL_GL_LOSE_CONTEXT_ON_RESET_ARB                   0x8252
 #define LOCAL_GL_LOSE_CONTEXT_ON_RESET_EXT                   0x8252
 #define LOCAL_GL_LOSE_CONTEXT_ON_RESET_KHR                   0x8252
 #define LOCAL_GL_LOWER_LEFT                                  0x8CA1
+#define LOCAL_GL_LOWER_LEFT_EXT                              0x8CA1
 #define LOCAL_GL_LOW_FLOAT                                   0x8DF0
 #define LOCAL_GL_LOW_INT                                     0x8DF3
 #define LOCAL_GL_LO_BIAS_NV                                  0x8715
 #define LOCAL_GL_LO_SCALE_NV                                 0x870F
 #define LOCAL_GL_LUID_SIZE_EXT                               8
 #define LOCAL_GL_LUMINANCE                                   0x1909
 #define LOCAL_GL_LUMINANCE12                                 0x8041
 #define LOCAL_GL_LUMINANCE12_ALPHA12                         0x8047
@@ -2548,37 +2577,42 @@
 #define LOCAL_GL_MAX_CLIENT_ATTRIB_STACK_DEPTH               0x0D3B
 #define LOCAL_GL_MAX_CLIPMAP_DEPTH_SGIX                      0x8177
 #define LOCAL_GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX              0x8178
 #define LOCAL_GL_MAX_CLIP_DISTANCES                          0x0D32
 #define LOCAL_GL_MAX_CLIP_DISTANCES_APPLE                    0x0D32
 #define LOCAL_GL_MAX_CLIP_DISTANCES_EXT                      0x0D32
 #define LOCAL_GL_MAX_CLIP_PLANES                             0x0D32
 #define LOCAL_GL_MAX_CLIP_PLANES_IMG                         0x0D32
+#define LOCAL_GL_MAX_COARSE_FRAGMENT_SAMPLES_NV              0x955F
 #define LOCAL_GL_MAX_COLOR_ATTACHMENTS                       0x8CDF
 #define LOCAL_GL_MAX_COLOR_ATTACHMENTS_EXT                   0x8CDF
 #define LOCAL_GL_MAX_COLOR_ATTACHMENTS_NV                    0x8CDF
+#define LOCAL_GL_MAX_COLOR_FRAMEBUFFER_SAMPLES_AMD           0x91B3
+#define LOCAL_GL_MAX_COLOR_FRAMEBUFFER_STORAGE_SAMPLES_AMD   0x91B4
 #define LOCAL_GL_MAX_COLOR_MATRIX_STACK_DEPTH                0x80B3
 #define LOCAL_GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI            0x80B3
 #define LOCAL_GL_MAX_COLOR_TEXTURE_SAMPLES                   0x910E
 #define LOCAL_GL_MAX_COMBINED_ATOMIC_COUNTERS                0x92D7
 #define LOCAL_GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS         0x92D1
 #define LOCAL_GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES        0x82FA
 #define LOCAL_GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT    0x82FA
 #define LOCAL_GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS     0x8266
 #define LOCAL_GL_MAX_COMBINED_DIMENSIONS                     0x8282
 #define LOCAL_GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS    0x8A33
 #define LOCAL_GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS    0x8A32
 #define LOCAL_GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT        0x8A32
 #define LOCAL_GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_OES        0x8A32
 #define LOCAL_GL_MAX_COMBINED_IMAGE_UNIFORMS                 0x90CF
 #define LOCAL_GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS       0x8F39
 #define LOCAL_GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT   0x8F39
+#define LOCAL_GL_MAX_COMBINED_MESH_UNIFORM_COMPONENTS_NV     0x8E67
 #define LOCAL_GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES        0x8F39
 #define LOCAL_GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS          0x90DC
+#define LOCAL_GL_MAX_COMBINED_TASK_UNIFORM_COMPONENTS_NV     0x8E6F
 #define LOCAL_GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS        0x8E1E
 #define LOCAL_GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_EXT    0x8E1E
 #define LOCAL_GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_OES    0x8E1E
 #define LOCAL_GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS     0x8E1F
 #define LOCAL_GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT 0x8E1F
 #define LOCAL_GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_OES 0x8E1F
 #define LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS            0x8B4D
 #define LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB        0x8B4D
@@ -2618,22 +2652,26 @@
 #define LOCAL_GL_MAX_DEBUG_MESSAGE_LENGTH                    0x9143
 #define LOCAL_GL_MAX_DEBUG_MESSAGE_LENGTH_AMD                0x9143
 #define LOCAL_GL_MAX_DEBUG_MESSAGE_LENGTH_ARB                0x9143
 #define LOCAL_GL_MAX_DEBUG_MESSAGE_LENGTH_KHR                0x9143
 #define LOCAL_GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV                0x90D1
 #define LOCAL_GL_MAX_DEEP_3D_TEXTURE_WIDTH_HEIGHT_NV         0x90D0
 #define LOCAL_GL_MAX_DEFORMATION_ORDER_SGIX                  0x8197
 #define LOCAL_GL_MAX_DEPTH                                   0x8280
+#define LOCAL_GL_MAX_DEPTH_STENCIL_FRAMEBUFFER_SAMPLES_AMD   0x91B5
 #define LOCAL_GL_MAX_DEPTH_TEXTURE_SAMPLES                   0x910F
+#define LOCAL_GL_MAX_DETACHED_BUFFERS_NV                     0x95AD
+#define LOCAL_GL_MAX_DETACHED_TEXTURES_NV                    0x95AC
 #define LOCAL_GL_MAX_DRAW_BUFFERS                            0x8824
 #define LOCAL_GL_MAX_DRAW_BUFFERS_ARB                        0x8824
 #define LOCAL_GL_MAX_DRAW_BUFFERS_ATI                        0x8824
 #define LOCAL_GL_MAX_DRAW_BUFFERS_EXT                        0x8824
 #define LOCAL_GL_MAX_DRAW_BUFFERS_NV                         0x8824
+#define LOCAL_GL_MAX_DRAW_MESH_TASKS_COUNT_NV                0x953D
 #define LOCAL_GL_MAX_DUAL_SOURCE_DRAW_BUFFERS                0x88FC
 #define LOCAL_GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT            0x88FC
 #define LOCAL_GL_MAX_ELEMENTS_INDICES                        0x80E9
 #define LOCAL_GL_MAX_ELEMENTS_INDICES_EXT                    0x80E9
 #define LOCAL_GL_MAX_ELEMENTS_VERTICES                       0x80E8
 #define LOCAL_GL_MAX_ELEMENTS_VERTICES_EXT                   0x80E8
 #define LOCAL_GL_MAX_ELEMENT_INDEX                           0x8D6B
 #define LOCAL_GL_MAX_EVAL_ORDER                              0x0D30
@@ -2715,16 +2753,29 @@
 #define LOCAL_GL_MAX_LABEL_LENGTH                            0x82E8
 #define LOCAL_GL_MAX_LABEL_LENGTH_KHR                        0x82E8
 #define LOCAL_GL_MAX_LAYERS                                  0x8281
 #define LOCAL_GL_MAX_LGPU_GPUS_NVX                           0x92BA
 #define LOCAL_GL_MAX_LIGHTS                                  0x0D31
 #define LOCAL_GL_MAX_LIST_NESTING                            0x0B31
 #define LOCAL_GL_MAX_MAP_TESSELLATION_NV                     0x86D6
 #define LOCAL_GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB          0x8841
+#define LOCAL_GL_MAX_MESH_ATOMIC_COUNTERS_NV                 0x8E65
+#define LOCAL_GL_MAX_MESH_ATOMIC_COUNTER_BUFFERS_NV          0x8E64
+#define LOCAL_GL_MAX_MESH_IMAGE_UNIFORMS_NV                  0x8E62
+#define LOCAL_GL_MAX_MESH_OUTPUT_PRIMITIVES_NV               0x9539
+#define LOCAL_GL_MAX_MESH_OUTPUT_VERTICES_NV                 0x9538
+#define LOCAL_GL_MAX_MESH_SHADER_STORAGE_BLOCKS_NV           0x8E66
+#define LOCAL_GL_MAX_MESH_TEXTURE_IMAGE_UNITS_NV             0x8E61
+#define LOCAL_GL_MAX_MESH_TOTAL_MEMORY_SIZE_NV               0x9536
+#define LOCAL_GL_MAX_MESH_UNIFORM_BLOCKS_NV                  0x8E60
+#define LOCAL_GL_MAX_MESH_UNIFORM_COMPONENTS_NV              0x8E63
+#define LOCAL_GL_MAX_MESH_VIEWS_NV                           0x9557
+#define LOCAL_GL_MAX_MESH_WORK_GROUP_INVOCATIONS_NV          0x95A2
+#define LOCAL_GL_MAX_MESH_WORK_GROUP_SIZE_NV                 0x953B
 #define LOCAL_GL_MAX_MODELVIEW_STACK_DEPTH                   0x0D36
 #define LOCAL_GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV           0x8E11
 #define LOCAL_GL_MAX_MULTIVIEW_BUFFERS_EXT                   0x90F2
 #define LOCAL_GL_MAX_NAME_LENGTH                             0x92F6
 #define LOCAL_GL_MAX_NAME_STACK_DEPTH                        0x0D37
 #define LOCAL_GL_MAX_NUM_ACTIVE_VARIABLES                    0x92F7
 #define LOCAL_GL_MAX_NUM_COMPATIBLE_SUBROUTINES              0x92F8
 #define LOCAL_GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT        0x87CA
@@ -2801,34 +2852,47 @@
 #define LOCAL_GL_MAX_SAMPLE_MASK_WORDS                       0x8E59
 #define LOCAL_GL_MAX_SAMPLE_MASK_WORDS_NV                    0x8E59
 #define LOCAL_GL_MAX_SERVER_WAIT_TIMEOUT                     0x9111
 #define LOCAL_GL_MAX_SERVER_WAIT_TIMEOUT_APPLE               0x9111
 #define LOCAL_GL_MAX_SHADER_BUFFER_ADDRESS_NV                0x8F35
 #define LOCAL_GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_FAST_SIZE_EXT     0x9650
 #define LOCAL_GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_SIZE_EXT  0x9651
 #define LOCAL_GL_MAX_SHADER_COMPILER_THREADS_ARB             0x91B0
+#define LOCAL_GL_MAX_SHADER_COMPILER_THREADS_KHR             0x91B0
 #define LOCAL_GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT        0x8F63
 #define LOCAL_GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_SIZE_EXT     0x8F67
 #define LOCAL_GL_MAX_SHADER_STORAGE_BLOCK_SIZE               0x90DE
 #define LOCAL_GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS          0x90DD
+#define LOCAL_GL_MAX_SHADER_SUBSAMPLED_IMAGE_UNITS_QCOM      0x8FA1
 #define LOCAL_GL_MAX_SHININESS_NV                            0x8504
 #define LOCAL_GL_MAX_SPARSE_3D_TEXTURE_SIZE_AMD              0x9199
 #define LOCAL_GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB              0x9199
 #define LOCAL_GL_MAX_SPARSE_3D_TEXTURE_SIZE_EXT              0x9199
 #define LOCAL_GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS             0x919A
 #define LOCAL_GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB         0x919A
 #define LOCAL_GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_EXT         0x919A
 #define LOCAL_GL_MAX_SPARSE_TEXTURE_SIZE_AMD                 0x9198
 #define LOCAL_GL_MAX_SPARSE_TEXTURE_SIZE_ARB                 0x9198
 #define LOCAL_GL_MAX_SPARSE_TEXTURE_SIZE_EXT                 0x9198
 #define LOCAL_GL_MAX_SPOT_EXPONENT_NV                        0x8505
 #define LOCAL_GL_MAX_SUBPIXEL_PRECISION_BIAS_BITS_NV         0x9349
 #define LOCAL_GL_MAX_SUBROUTINES                             0x8DE7
 #define LOCAL_GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS            0x8DE8
+#define LOCAL_GL_MAX_TASK_ATOMIC_COUNTERS_NV                 0x8E6D
+#define LOCAL_GL_MAX_TASK_ATOMIC_COUNTER_BUFFERS_NV          0x8E6C
+#define LOCAL_GL_MAX_TASK_IMAGE_UNIFORMS_NV                  0x8E6A
+#define LOCAL_GL_MAX_TASK_OUTPUT_COUNT_NV                    0x953A
+#define LOCAL_GL_MAX_TASK_SHADER_STORAGE_BLOCKS_NV           0x8E6E
+#define LOCAL_GL_MAX_TASK_TEXTURE_IMAGE_UNITS_NV             0x8E69
+#define LOCAL_GL_MAX_TASK_TOTAL_MEMORY_SIZE_NV               0x9537
+#define LOCAL_GL_MAX_TASK_UNIFORM_BLOCKS_NV                  0x8E68
+#define LOCAL_GL_MAX_TASK_UNIFORM_COMPONENTS_NV              0x8E6B
+#define LOCAL_GL_MAX_TASK_WORK_GROUP_INVOCATIONS_NV          0x95A3
+#define LOCAL_GL_MAX_TASK_WORK_GROUP_SIZE_NV                 0x953C
 #define LOCAL_GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS            0x92D3
 #define LOCAL_GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_EXT        0x92D3
 #define LOCAL_GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_OES        0x92D3
 #define LOCAL_GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS     0x92CD
 #define LOCAL_GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_EXT 0x92CD
 #define LOCAL_GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_OES 0x92CD
 #define LOCAL_GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS             0x90CB
 #define LOCAL_GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT         0x90CB
@@ -2894,16 +2958,17 @@
 #define LOCAL_GL_MAX_TEXTURE_COORDS                          0x8871
 #define LOCAL_GL_MAX_TEXTURE_COORDS_ARB                      0x8871
 #define LOCAL_GL_MAX_TEXTURE_COORDS_NV                       0x8871
 #define LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS                     0x8872
 #define LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS_ARB                 0x8872
 #define LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS_NV                  0x8872
 #define LOCAL_GL_MAX_TEXTURE_LOD_BIAS                        0x84FD
 #define LOCAL_GL_MAX_TEXTURE_LOD_BIAS_EXT                    0x84FD
+#define LOCAL_GL_MAX_TEXTURE_MAX_ANISOTROPY                  0x84FF
 #define LOCAL_GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT              0x84FF
 #define LOCAL_GL_MAX_TEXTURE_SIZE                            0x0D33
 #define LOCAL_GL_MAX_TEXTURE_STACK_DEPTH                     0x0D39
 #define LOCAL_GL_MAX_TEXTURE_UNITS                           0x84E2
 #define LOCAL_GL_MAX_TEXTURE_UNITS_ARB                       0x84E2
 #define LOCAL_GL_MAX_TRACK_MATRICES_NV                       0x862F
 #define LOCAL_GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV             0x862E
 #define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_BUFFERS              0x8E70
@@ -2958,16 +3023,29 @@
 #define LOCAL_GL_MAX_VIEWPORTS_NV                            0x825B
 #define LOCAL_GL_MAX_VIEWPORTS_OES                           0x825B
 #define LOCAL_GL_MAX_VIEWPORT_DIMS                           0x0D3A
 #define LOCAL_GL_MAX_VIEWS_OVR                               0x9631
 #define LOCAL_GL_MAX_WIDTH                                   0x827E
 #define LOCAL_GL_MAX_WINDOW_RECTANGLES_EXT                   0x8F14
 #define LOCAL_GL_MEDIUM_FLOAT                                0x8DF1
 #define LOCAL_GL_MEDIUM_INT                                  0x8DF4
+#define LOCAL_GL_MEMORY_ATTACHABLE_ALIGNMENT_NV              0x95A6
+#define LOCAL_GL_MEMORY_ATTACHABLE_NV                        0x95A8
+#define LOCAL_GL_MEMORY_ATTACHABLE_SIZE_NV                   0x95A7
+#define LOCAL_GL_MESH_OUTPUT_PER_PRIMITIVE_GRANULARITY_NV    0x9543
+#define LOCAL_GL_MESH_OUTPUT_PER_VERTEX_GRANULARITY_NV       0x92DF
+#define LOCAL_GL_MESH_OUTPUT_TYPE_NV                         0x957B
+#define LOCAL_GL_MESH_PRIMITIVES_OUT_NV                      0x957A
+#define LOCAL_GL_MESH_SHADER_BIT_NV                          0x00000040
+#define LOCAL_GL_MESH_SHADER_NV                              0x9559
+#define LOCAL_GL_MESH_SUBROUTINE_NV                          0x957C
+#define LOCAL_GL_MESH_SUBROUTINE_UNIFORM_NV                  0x957E
+#define LOCAL_GL_MESH_VERTICES_OUT_NV                        0x9579
+#define LOCAL_GL_MESH_WORK_GROUP_SIZE_NV                     0x953E
 #define LOCAL_GL_MIN                                         0x8007
 #define LOCAL_GL_MINMAX                                      0x802E
 #define LOCAL_GL_MINMAX_EXT                                  0x802E
 #define LOCAL_GL_MINMAX_FORMAT                               0x802F
 #define LOCAL_GL_MINMAX_FORMAT_EXT                           0x802F
 #define LOCAL_GL_MINMAX_SINK                                 0x8030
 #define LOCAL_GL_MINMAX_SINK_EXT                             0x8030
 #define LOCAL_GL_MINOR_VERSION                               0x821C
@@ -3102,16 +3180,17 @@
 #define LOCAL_GL_NEAREST                                     0x2600
 #define LOCAL_GL_NEAREST_CLIPMAP_LINEAR_SGIX                 0x844E
 #define LOCAL_GL_NEAREST_CLIPMAP_NEAREST_SGIX                0x844D
 #define LOCAL_GL_NEAREST_MIPMAP_LINEAR                       0x2702
 #define LOCAL_GL_NEAREST_MIPMAP_NEAREST                      0x2700
 #define LOCAL_GL_NEGATE_BIT_ATI                              0x00000004
 #define LOCAL_GL_NEGATIVE_ONE_EXT                            0x87DF
 #define LOCAL_GL_NEGATIVE_ONE_TO_ONE                         0x935E
+#define LOCAL_GL_NEGATIVE_ONE_TO_ONE_EXT                     0x935E
 #define LOCAL_GL_NEGATIVE_W_EXT                              0x87DC
 #define LOCAL_GL_NEGATIVE_X_EXT                              0x87D9
 #define LOCAL_GL_NEGATIVE_Y_EXT                              0x87DA
 #define LOCAL_GL_NEGATIVE_Z_EXT                              0x87DB
 #define LOCAL_GL_NEVER                                       0x0200
 #define LOCAL_GL_NEXT_BUFFER_NV                              -2
 #define LOCAL_GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV         0x9025
 #define LOCAL_GL_NICEST                                      0x1102
@@ -3168,16 +3247,18 @@
 #define LOCAL_GL_NUM_PASSES_ATI                              0x8970
 #define LOCAL_GL_NUM_PROGRAM_BINARY_FORMATS                  0x87FE
 #define LOCAL_GL_NUM_PROGRAM_BINARY_FORMATS_OES              0x87FE
 #define LOCAL_GL_NUM_SAMPLE_COUNTS                           0x9380
 #define LOCAL_GL_NUM_SHADER_BINARY_FORMATS                   0x8DF9
 #define LOCAL_GL_NUM_SHADING_LANGUAGE_VERSIONS               0x82E9
 #define LOCAL_GL_NUM_SPARSE_LEVELS_ARB                       0x91AA
 #define LOCAL_GL_NUM_SPARSE_LEVELS_EXT                       0x91AA
+#define LOCAL_GL_NUM_SPIR_V_EXTENSIONS                       0x9554
+#define LOCAL_GL_NUM_SUPPORTED_MULTISAMPLE_MODES_AMD         0x91B6
 #define LOCAL_GL_NUM_TILING_TYPES_EXT                        0x9582
 #define LOCAL_GL_NUM_VIDEO_CAPTURE_STREAMS_NV                0x9024
 #define LOCAL_GL_NUM_VIRTUAL_PAGE_SIZES_ARB                  0x91A8
 #define LOCAL_GL_NUM_VIRTUAL_PAGE_SIZES_EXT                  0x91A8
 #define LOCAL_GL_NUM_WINDOW_RECTANGLES_EXT                   0x8F15
 #define LOCAL_GL_OBJECT_ACTIVE_ATTRIBUTES_ARB                0x8B89
 #define LOCAL_GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB      0x8B8A
 #define LOCAL_GL_OBJECT_ACTIVE_UNIFORMS_ARB                  0x8B86
@@ -3357,17 +3438,19 @@
 #define LOCAL_GL_PALETTE4_RGBA4_OES                          0x8B93
 #define LOCAL_GL_PALETTE4_RGBA8_OES                          0x8B91
 #define LOCAL_GL_PALETTE8_R5_G6_B5_OES                       0x8B97
 #define LOCAL_GL_PALETTE8_RGB5_A1_OES                        0x8B99
 #define LOCAL_GL_PALETTE8_RGB8_OES                           0x8B95
 #define LOCAL_GL_PALETTE8_RGBA4_OES                          0x8B98
 #define LOCAL_GL_PALETTE8_RGBA8_OES                          0x8B96
 #define LOCAL_GL_PARALLEL_ARRAYS_INTEL                       0x83F4
+#define LOCAL_GL_PARAMETER_BUFFER                            0x80EE
 #define LOCAL_GL_PARAMETER_BUFFER_ARB                        0x80EE
+#define LOCAL_GL_PARAMETER_BUFFER_BINDING                    0x80EF
 #define LOCAL_GL_PARAMETER_BUFFER_BINDING_ARB                0x80EF
 #define LOCAL_GL_PARTIAL_SUCCESS_NV                          0x902E
 #define LOCAL_GL_PASS_THROUGH_NV                             0x86E6
 #define LOCAL_GL_PASS_THROUGH_TOKEN                          0x0700
 #define LOCAL_GL_PATCHES                                     0x000E
 #define LOCAL_GL_PATCHES_EXT                                 0x000E
 #define LOCAL_GL_PATCHES_OES                                 0x000E
 #define LOCAL_GL_PATCH_DEFAULT_INNER_LEVEL                   0x8E73
@@ -3493,17 +3576,19 @@
 #define LOCAL_GL_PIXEL_MAP_S_TO_S_SIZE                       0x0CB1
 #define LOCAL_GL_PIXEL_MIN_FILTER_EXT                        0x8332
 #define LOCAL_GL_PIXEL_MODE_BIT                              0x00000020
 #define LOCAL_GL_PIXEL_PACK_BUFFER                           0x88EB
 #define LOCAL_GL_PIXEL_PACK_BUFFER_ARB                       0x88EB
 #define LOCAL_GL_PIXEL_PACK_BUFFER_BINDING                   0x88ED
 #define LOCAL_GL_PIXEL_PACK_BUFFER_BINDING_ARB               0x88ED
 #define LOCAL_GL_PIXEL_PACK_BUFFER_BINDING_EXT               0x88ED
+#define LOCAL_GL_PIXEL_PACK_BUFFER_BINDING_NV                0x88ED
 #define LOCAL_GL_PIXEL_PACK_BUFFER_EXT                       0x88EB
+#define LOCAL_GL_PIXEL_PACK_BUFFER_NV                        0x88EB
 #define LOCAL_GL_PIXEL_SUBSAMPLE_2424_SGIX                   0x85A3
 #define LOCAL_GL_PIXEL_SUBSAMPLE_4242_SGIX                   0x85A4
 #define LOCAL_GL_PIXEL_SUBSAMPLE_4444_SGIX                   0x85A2
 #define LOCAL_GL_PIXEL_TEXTURE_SGIS                          0x8353
 #define LOCAL_GL_PIXEL_TEX_GEN_ALPHA_LS_SGIX                 0x8189
 #define LOCAL_GL_PIXEL_TEX_GEN_ALPHA_MS_SGIX                 0x818A
 #define LOCAL_GL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX         0x8188
 #define LOCAL_GL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX            0x8187
@@ -3523,17 +3608,19 @@
 #define LOCAL_GL_PIXEL_TRANSFORM_2D_EXT                      0x8330
 #define LOCAL_GL_PIXEL_TRANSFORM_2D_MATRIX_EXT               0x8338
 #define LOCAL_GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT          0x8336
 #define LOCAL_GL_PIXEL_UNPACK_BUFFER                         0x88EC
 #define LOCAL_GL_PIXEL_UNPACK_BUFFER_ARB                     0x88EC
 #define LOCAL_GL_PIXEL_UNPACK_BUFFER_BINDING                 0x88EF
 #define LOCAL_GL_PIXEL_UNPACK_BUFFER_BINDING_ARB             0x88EF
 #define LOCAL_GL_PIXEL_UNPACK_BUFFER_BINDING_EXT             0x88EF
+#define LOCAL_GL_PIXEL_UNPACK_BUFFER_BINDING_NV              0x88EF
 #define LOCAL_GL_PIXEL_UNPACK_BUFFER_EXT                     0x88EC
+#define LOCAL_GL_PIXEL_UNPACK_BUFFER_NV                      0x88EC
 #define LOCAL_GL_PLUS_CLAMPED_ALPHA_NV                       0x92B2
 #define LOCAL_GL_PLUS_CLAMPED_NV                             0x92B1
 #define LOCAL_GL_PLUS_DARKER_NV                              0x9292
 #define LOCAL_GL_PLUS_NV                                     0x9291
 #define LOCAL_GL_PN_TRIANGLES_ATI                            0x87F0
 #define LOCAL_GL_PN_TRIANGLES_NORMAL_MODE_ATI                0x87F3
 #define LOCAL_GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI         0x87F7
 #define LOCAL_GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI      0x87F8
@@ -3576,16 +3663,17 @@
 #define LOCAL_GL_POINT_SPRITE_OES                            0x8861
 #define LOCAL_GL_POINT_SPRITE_R_MODE_NV                      0x8863
 #define LOCAL_GL_POINT_TOKEN                                 0x0701
 #define LOCAL_GL_POLYGON                                     0x0009
 #define LOCAL_GL_POLYGON_BIT                                 0x00000008
 #define LOCAL_GL_POLYGON_MODE                                0x0B40
 #define LOCAL_GL_POLYGON_MODE_NV                             0x0B40
 #define LOCAL_GL_POLYGON_OFFSET_BIAS_EXT                     0x8039
+#define LOCAL_GL_POLYGON_OFFSET_CLAMP                        0x8E1B
 #define LOCAL_GL_POLYGON_OFFSET_CLAMP_EXT                    0x8E1B
 #define LOCAL_GL_POLYGON_OFFSET_COMMAND_NV                   0x000E
 #define LOCAL_GL_POLYGON_OFFSET_EXT                          0x8037
 #define LOCAL_GL_POLYGON_OFFSET_FACTOR                       0x8038
 #define LOCAL_GL_POLYGON_OFFSET_FACTOR_EXT                   0x8038
 #define LOCAL_GL_POLYGON_OFFSET_FILL                         0x8037
 #define LOCAL_GL_POLYGON_OFFSET_LINE                         0x2A02
 #define LOCAL_GL_POLYGON_OFFSET_LINE_NV                      0x2A02
@@ -3650,16 +3738,17 @@
 #define LOCAL_GL_PRIMARY_COLOR                               0x8577
 #define LOCAL_GL_PRIMARY_COLOR_ARB                           0x8577
 #define LOCAL_GL_PRIMARY_COLOR_EXT                           0x8577
 #define LOCAL_GL_PRIMARY_COLOR_NV                            0x852C
 #define LOCAL_GL_PRIMITIVES_GENERATED                        0x8C87
 #define LOCAL_GL_PRIMITIVES_GENERATED_EXT                    0x8C87
 #define LOCAL_GL_PRIMITIVES_GENERATED_NV                     0x8C87
 #define LOCAL_GL_PRIMITIVES_GENERATED_OES                    0x8C87
+#define LOCAL_GL_PRIMITIVES_SUBMITTED                        0x82EF
 #define LOCAL_GL_PRIMITIVES_SUBMITTED_ARB                    0x82EF
 #define LOCAL_GL_PRIMITIVE_BOUNDING_BOX                      0x92BE
 #define LOCAL_GL_PRIMITIVE_BOUNDING_BOX_ARB                  0x92BE
 #define LOCAL_GL_PRIMITIVE_BOUNDING_BOX_EXT                  0x92BE
 #define LOCAL_GL_PRIMITIVE_BOUNDING_BOX_OES                  0x92BE
 #define LOCAL_GL_PRIMITIVE_ID_NV                             0x8C7C
 #define LOCAL_GL_PRIMITIVE_RESTART                           0x8F9D
 #define LOCAL_GL_PRIMITIVE_RESTART_FIXED_INDEX               0x8D69
@@ -3675,16 +3764,17 @@
 #define LOCAL_GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_NV  0x9340
 #define LOCAL_GL_PROGRAM_ADDRESS_REGISTERS_ARB               0x88B0
 #define LOCAL_GL_PROGRAM_ALU_INSTRUCTIONS_ARB                0x8805
 #define LOCAL_GL_PROGRAM_ATTRIBS_ARB                         0x88AC
 #define LOCAL_GL_PROGRAM_ATTRIB_COMPONENTS_NV                0x8906
 #define LOCAL_GL_PROGRAM_BINARY_ANGLE                        0x93A6
 #define LOCAL_GL_PROGRAM_BINARY_FORMATS                      0x87FF
 #define LOCAL_GL_PROGRAM_BINARY_FORMATS_OES                  0x87FF
+#define LOCAL_GL_PROGRAM_BINARY_FORMAT_MESA                  0x875F
 #define LOCAL_GL_PROGRAM_BINARY_LENGTH                       0x8741
 #define LOCAL_GL_PROGRAM_BINARY_LENGTH_OES                   0x8741
 #define LOCAL_GL_PROGRAM_BINARY_RETRIEVABLE_HINT             0x8257
 #define LOCAL_GL_PROGRAM_BINDING_ARB                         0x8677
 #define LOCAL_GL_PROGRAM_ERROR_POSITION_ARB                  0x864B
 #define LOCAL_GL_PROGRAM_ERROR_POSITION_NV                   0x864B
 #define LOCAL_GL_PROGRAM_ERROR_STRING_ARB                    0x8874
 #define LOCAL_GL_PROGRAM_ERROR_STRING_NV                     0x8874
@@ -3809,16 +3899,22 @@
 #define LOCAL_GL_QUERY_DEPTH_FAIL_EVENT_BIT_AMD              0x00000002
 #define LOCAL_GL_QUERY_DEPTH_PASS_EVENT_BIT_AMD              0x00000001
 #define LOCAL_GL_QUERY_KHR                                   0x82E3
 #define LOCAL_GL_QUERY_NO_WAIT                               0x8E14
 #define LOCAL_GL_QUERY_NO_WAIT_INVERTED                      0x8E18
 #define LOCAL_GL_QUERY_NO_WAIT_NV                            0x8E14
 #define LOCAL_GL_QUERY_OBJECT_AMD                            0x9153
 #define LOCAL_GL_QUERY_OBJECT_EXT                            0x9153
+#define LOCAL_GL_QUERY_RESOURCE_BUFFEROBJECT_NV              0x9547
+#define LOCAL_GL_QUERY_RESOURCE_MEMTYPE_VIDMEM_NV            0x9542
+#define LOCAL_GL_QUERY_RESOURCE_RENDERBUFFER_NV              0x9546
+#define LOCAL_GL_QUERY_RESOURCE_SYS_RESERVED_NV              0x9544
+#define LOCAL_GL_QUERY_RESOURCE_TEXTURE_NV                   0x9545
+#define LOCAL_GL_QUERY_RESOURCE_TYPE_VIDMEM_ALLOC_NV         0x9540
 #define LOCAL_GL_QUERY_RESULT                                0x8866
 #define LOCAL_GL_QUERY_RESULT_ARB                            0x8866
 #define LOCAL_GL_QUERY_RESULT_AVAILABLE                      0x8867
 #define LOCAL_GL_QUERY_RESULT_AVAILABLE_ARB                  0x8867
 #define LOCAL_GL_QUERY_RESULT_AVAILABLE_EXT                  0x8867
 #define LOCAL_GL_QUERY_RESULT_EXT                            0x8866
 #define LOCAL_GL_QUERY_RESULT_NO_WAIT                        0x9194
 #define LOCAL_GL_QUERY_RESULT_NO_WAIT_AMD                    0x9194
@@ -3904,16 +4000,18 @@
 #define LOCAL_GL_RED_NV                                      0x1903
 #define LOCAL_GL_RED_SCALE                                   0x0D14
 #define LOCAL_GL_RED_SNORM                                   0x8F90
 #define LOCAL_GL_REFERENCED_BY_COMPUTE_SHADER                0x930B
 #define LOCAL_GL_REFERENCED_BY_FRAGMENT_SHADER               0x930A
 #define LOCAL_GL_REFERENCED_BY_GEOMETRY_SHADER               0x9309
 #define LOCAL_GL_REFERENCED_BY_GEOMETRY_SHADER_EXT           0x9309
 #define LOCAL_GL_REFERENCED_BY_GEOMETRY_SHADER_OES           0x9309
+#define LOCAL_GL_REFERENCED_BY_MESH_SHADER_NV                0x95A0
+#define LOCAL_GL_REFERENCED_BY_TASK_SHADER_NV                0x95A1
 #define LOCAL_GL_REFERENCED_BY_TESS_CONTROL_SHADER           0x9307
 #define LOCAL_GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT       0x9307
 #define LOCAL_GL_REFERENCED_BY_TESS_CONTROL_SHADER_OES       0x9307
 #define LOCAL_GL_REFERENCED_BY_TESS_EVALUATION_SHADER        0x9308
 #define LOCAL_GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT    0x9308
 #define LOCAL_GL_REFERENCED_BY_TESS_EVALUATION_SHADER_OES    0x9308
 #define LOCAL_GL_REFERENCED_BY_VERTEX_SHADER                 0x9306
 #define LOCAL_GL_REFERENCE_PLANE_EQUATION_SGIX               0x817E
@@ -4012,16 +4110,17 @@
 #define LOCAL_GL_RENDERBUFFER_SAMPLES_ANGLE                  0x8CAB
 #define LOCAL_GL_RENDERBUFFER_SAMPLES_APPLE                  0x8CAB
 #define LOCAL_GL_RENDERBUFFER_SAMPLES_EXT                    0x8CAB
 #define LOCAL_GL_RENDERBUFFER_SAMPLES_IMG                    0x9133
 #define LOCAL_GL_RENDERBUFFER_SAMPLES_NV                     0x8CAB
 #define LOCAL_GL_RENDERBUFFER_STENCIL_SIZE                   0x8D55
 #define LOCAL_GL_RENDERBUFFER_STENCIL_SIZE_EXT               0x8D55
 #define LOCAL_GL_RENDERBUFFER_STENCIL_SIZE_OES               0x8D55
+#define LOCAL_GL_RENDERBUFFER_STORAGE_SAMPLES_AMD            0x91B2
 #define LOCAL_GL_RENDERBUFFER_WIDTH                          0x8D42
 #define LOCAL_GL_RENDERBUFFER_WIDTH_EXT                      0x8D42
 #define LOCAL_GL_RENDERBUFFER_WIDTH_OES                      0x8D42
 #define LOCAL_GL_RENDERER                                    0x1F01
 #define LOCAL_GL_RENDER_DIRECT_TO_FRAMEBUFFER_QCOM           0x8FB3
 #define LOCAL_GL_RENDER_GPU_MASK_NV                          0x9558
 #define LOCAL_GL_RENDER_MODE                                 0x0C40
 #define LOCAL_GL_REPEAT                                      0x2901
@@ -4032,16 +4131,17 @@
 #define LOCAL_GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN             0x85C1
 #define LOCAL_GL_REPLACEMENT_CODE_SUN                        0x81D8
 #define LOCAL_GL_REPLACE_EXT                                 0x8062
 #define LOCAL_GL_REPLACE_MIDDLE_SUN                          0x0002
 #define LOCAL_GL_REPLACE_OLDEST_SUN                          0x0003
 #define LOCAL_GL_REPLACE_VALUE_AMD                           0x874B
 #define LOCAL_GL_REPLICATE_BORDER                            0x8153
 #define LOCAL_GL_REPLICATE_BORDER_HP                         0x8153
+#define LOCAL_GL_REPRESENTATIVE_FRAGMENT_TEST_NV             0x937F
 #define LOCAL_GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES            0x8D68
 #define LOCAL_GL_RESAMPLE_AVERAGE_OML                        0x8988
 #define LOCAL_GL_RESAMPLE_DECIMATE_OML                       0x8989
 #define LOCAL_GL_RESAMPLE_DECIMATE_SGIX                      0x8430
 #define LOCAL_GL_RESAMPLE_REPLICATE_OML                      0x8986
 #define LOCAL_GL_RESAMPLE_REPLICATE_SGIX                     0x8433
 #define LOCAL_GL_RESAMPLE_ZERO_FILL_OML                      0x8987
 #define LOCAL_GL_RESAMPLE_ZERO_FILL_SGIX                     0x8434
@@ -4184,16 +4284,17 @@
 #define LOCAL_GL_RGB_SCALE                                   0x8573
 #define LOCAL_GL_RGB_SCALE_ARB                               0x8573
 #define LOCAL_GL_RGB_SCALE_EXT                               0x8573
 #define LOCAL_GL_RGB_SNORM                                   0x8F92
 #define LOCAL_GL_RG_EXT                                      0x8227
 #define LOCAL_GL_RG_INTEGER                                  0x8228
 #define LOCAL_GL_RG_SNORM                                    0x8F91
 #define LOCAL_GL_RIGHT                                       0x0407
+#define LOCAL_GL_ROBUST_GPU_TIMEOUT_MS_KHR                   0x82FD
 #define LOCAL_GL_ROUNDED_RECT2_NV                            0xEA
 #define LOCAL_GL_ROUNDED_RECT4_NV                            0xEC
 #define LOCAL_GL_ROUNDED_RECT8_NV                            0xEE
 #define LOCAL_GL_ROUNDED_RECT_NV                             0xE8
 #define LOCAL_GL_ROUND_NV                                    0x90A4
 #define LOCAL_GL_S                                           0x2000
 #define LOCAL_GL_SAMPLER                                     0x82E6
 #define LOCAL_GL_SAMPLER_1D                                  0x8B5D
@@ -4303,18 +4404,20 @@
 #define LOCAL_GL_SCALEBIAS_HINT_SGIX                         0x8322
 #define LOCAL_GL_SCALED_RESOLVE_FASTEST_EXT                  0x90BA
 #define LOCAL_GL_SCALED_RESOLVE_NICEST_EXT                   0x90BB
 #define LOCAL_GL_SCALE_BY_FOUR_NV                            0x853F
 #define LOCAL_GL_SCALE_BY_ONE_HALF_NV                        0x8540
 #define LOCAL_GL_SCALE_BY_TWO_NV                             0x853E
 #define LOCAL_GL_SCISSOR_BIT                                 0x00080000
 #define LOCAL_GL_SCISSOR_BOX                                 0x0C10
+#define LOCAL_GL_SCISSOR_BOX_EXCLUSIVE_NV                    0x9556
 #define LOCAL_GL_SCISSOR_COMMAND_NV                          0x0011
 #define LOCAL_GL_SCISSOR_TEST                                0x0C11
+#define LOCAL_GL_SCISSOR_TEST_EXCLUSIVE_NV                   0x9555
 #define LOCAL_GL_SCREEN                                      0x9295
 #define LOCAL_GL_SCREEN_COORDINATES_REND                     0x8490
 #define LOCAL_GL_SCREEN_KHR                                  0x9295
 #define LOCAL_GL_SCREEN_NV                                   0x9295
 #define LOCAL_GL_SECONDARY_COLOR_ARRAY                       0x845E
 #define LOCAL_GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV            0x8F27
 #define LOCAL_GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING        0x889C
 #define LOCAL_GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB    0x889C
@@ -4344,16 +4447,17 @@
 #define LOCAL_GL_SEPARATE_SPECULAR_COLOR_EXT                 0x81FA
 #define LOCAL_GL_SET                                         0x150F
 #define LOCAL_GL_SET_AMD                                     0x874A
 #define LOCAL_GL_SGX_BINARY_IMG                              0x8C0A
 #define LOCAL_GL_SGX_PROGRAM_BINARY_IMG                      0x9130
 #define LOCAL_GL_SHADER                                      0x82E1
 #define LOCAL_GL_SHADER_BINARY_DMP                           0x9250
 #define LOCAL_GL_SHADER_BINARY_FORMATS                       0x8DF8
+#define LOCAL_GL_SHADER_BINARY_FORMAT_SPIR_V                 0x9551
 #define LOCAL_GL_SHADER_BINARY_FORMAT_SPIR_V_ARB             0x9551
 #define LOCAL_GL_SHADER_BINARY_VIV                           0x8FC4
 #define LOCAL_GL_SHADER_COMPILER                             0x8DFA
 #define LOCAL_GL_SHADER_CONSISTENT_NV                        0x86DD
 #define LOCAL_GL_SHADER_GLOBAL_ACCESS_BARRIER_BIT_NV         0x00000010
 #define LOCAL_GL_SHADER_IMAGE_ACCESS_BARRIER_BIT             0x00000020
 #define LOCAL_GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT         0x00000020
 #define LOCAL_GL_SHADER_IMAGE_ATOMIC                         0x82A6
@@ -4372,16 +4476,36 @@
 #define LOCAL_GL_SHADER_STORAGE_BUFFER_BINDING               0x90D3
 #define LOCAL_GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT      0x90DF
 #define LOCAL_GL_SHADER_STORAGE_BUFFER_SIZE                  0x90D5
 #define LOCAL_GL_SHADER_STORAGE_BUFFER_START                 0x90D4
 #define LOCAL_GL_SHADER_TYPE                                 0x8B4F
 #define LOCAL_GL_SHADE_MODEL                                 0x0B54
 #define LOCAL_GL_SHADING_LANGUAGE_VERSION                    0x8B8C
 #define LOCAL_GL_SHADING_LANGUAGE_VERSION_ARB                0x8B8C
+#define LOCAL_GL_SHADING_RATE_16_INVOCATIONS_PER_PIXEL_NV    0x956F
+#define LOCAL_GL_SHADING_RATE_1_INVOCATION_PER_1X2_PIXELS_NV 0x9566
+#define LOCAL_GL_SHADING_RATE_1_INVOCATION_PER_2X1_PIXELS_NV 0x9567
+#define LOCAL_GL_SHADING_RATE_1_INVOCATION_PER_2X2_PIXELS_NV 0x9568
+#define LOCAL_GL_SHADING_RATE_1_INVOCATION_PER_2X4_PIXELS_NV 0x9569
+#define LOCAL_GL_SHADING_RATE_1_INVOCATION_PER_4X2_PIXELS_NV 0x956A
+#define LOCAL_GL_SHADING_RATE_1_INVOCATION_PER_4X4_PIXELS_NV 0x956B
+#define LOCAL_GL_SHADING_RATE_1_INVOCATION_PER_PIXEL_NV      0x9565
+#define LOCAL_GL_SHADING_RATE_2_INVOCATIONS_PER_PIXEL_NV     0x956C
+#define LOCAL_GL_SHADING_RATE_4_INVOCATIONS_PER_PIXEL_NV     0x956D
+#define LOCAL_GL_SHADING_RATE_8_INVOCATIONS_PER_PIXEL_NV     0x956E
+#define LOCAL_GL_SHADING_RATE_IMAGE_BINDING_NV               0x955B
+#define LOCAL_GL_SHADING_RATE_IMAGE_NV                       0x9563
+#define LOCAL_GL_SHADING_RATE_IMAGE_PALETTE_SIZE_NV          0x955E
+#define LOCAL_GL_SHADING_RATE_IMAGE_TEXEL_HEIGHT_NV          0x955D
+#define LOCAL_GL_SHADING_RATE_IMAGE_TEXEL_WIDTH_NV           0x955C
+#define LOCAL_GL_SHADING_RATE_NO_INVOCATIONS_NV              0x9564
+#define LOCAL_GL_SHADING_RATE_SAMPLE_ORDER_DEFAULT_NV        0x95AE
+#define LOCAL_GL_SHADING_RATE_SAMPLE_ORDER_PIXEL_MAJOR_NV    0x95AF
+#define LOCAL_GL_SHADING_RATE_SAMPLE_ORDER_SAMPLE_MAJOR_NV   0x95B0
 #define LOCAL_GL_SHADOW_AMBIENT_SGIX                         0x80BF
 #define LOCAL_GL_SHADOW_ATTENUATION_EXT                      0x834E
 #define LOCAL_GL_SHARED_EDGE_NV                              0xC0
 #define LOCAL_GL_SHARED_TEXTURE_PALETTE_EXT                  0x81FB
 #define LOCAL_GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS            0x80B0
 #define LOCAL_GL_SHININESS                                   0x1601
 #define LOCAL_GL_SHORT                                       0x1402
 #define LOCAL_GL_SIGNALED                                    0x9119
@@ -4473,17 +4597,19 @@
 #define LOCAL_GL_SPARE0_PLUS_SECONDARY_COLOR_NV              0x8532
 #define LOCAL_GL_SPARE1_NV                                   0x852F
 #define LOCAL_GL_SPARSE_BUFFER_PAGE_SIZE_ARB                 0x82F8
 #define LOCAL_GL_SPARSE_STORAGE_BIT_ARB                      0x0400
 #define LOCAL_GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB  0x91A9
 #define LOCAL_GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_EXT  0x91A9
 #define LOCAL_GL_SPECULAR                                    0x1202
 #define LOCAL_GL_SPHERE_MAP                                  0x2402
+#define LOCAL_GL_SPIR_V_BINARY                               0x9552
 #define LOCAL_GL_SPIR_V_BINARY_ARB                           0x9552
+#define LOCAL_GL_SPIR_V_EXTENSIONS                           0x9553
 #define LOCAL_GL_SPOT_CUTOFF                                 0x1206
 #define LOCAL_GL_SPOT_DIRECTION                              0x1204
 #define LOCAL_GL_SPOT_EXPONENT                               0x1205
 #define LOCAL_GL_SPRITE_AXIAL_SGIX                           0x814C
 #define LOCAL_GL_SPRITE_AXIS_SGIX                            0x814A
 #define LOCAL_GL_SPRITE_EYE_ALIGNED_SGIX                     0x814E
 #define LOCAL_GL_SPRITE_MODE_SGIX                            0x8149
 #define LOCAL_GL_SPRITE_OBJECT_ALIGNED_SGIX                  0x814D
@@ -4614,16 +4740,17 @@
 #define LOCAL_GL_SUBPIXEL_PRECISION_BIAS_Y_BITS_NV           0x9348
 #define LOCAL_GL_SUBSAMPLE_DISTANCE_AMD                      0x883F
 #define LOCAL_GL_SUBTRACT                                    0x84E7
 #define LOCAL_GL_SUBTRACT_ARB                                0x84E7
 #define LOCAL_GL_SUB_ATI                                     0x8965
 #define LOCAL_GL_SUCCESS_NV                                  0x902F
 #define LOCAL_GL_SUPERSAMPLE_SCALE_X_NV                      0x9372
 #define LOCAL_GL_SUPERSAMPLE_SCALE_Y_NV                      0x9373
+#define LOCAL_GL_SUPPORTED_MULTISAMPLE_MODES_AMD             0x91B7
 #define LOCAL_GL_SURFACE_MAPPED_NV                           0x8700
 #define LOCAL_GL_SURFACE_REGISTERED_NV                       0x86FD
 #define LOCAL_GL_SURFACE_STATE_NV                            0x86EB
 #define LOCAL_GL_SWIZZLE_STQ_ATI                             0x8977
 #define LOCAL_GL_SWIZZLE_STQ_DQ_ATI                          0x8979
 #define LOCAL_GL_SWIZZLE_STRQ_ATI                            0x897A
 #define LOCAL_GL_SWIZZLE_STRQ_DQ_ATI                         0x897B
 #define LOCAL_GL_SWIZZLE_STR_ATI                             0x8976
@@ -4658,41 +4785,48 @@
 #define LOCAL_GL_T4F_C4F_N3F_V4F                             0x2A2D
 #define LOCAL_GL_T4F_V4F                                     0x2A28
 #define LOCAL_GL_TABLE_TOO_LARGE                             0x8031
 #define LOCAL_GL_TABLE_TOO_LARGE_EXT                         0x8031
 #define LOCAL_GL_TANGENT_ARRAY_EXT                           0x8439
 #define LOCAL_GL_TANGENT_ARRAY_POINTER_EXT                   0x8442
 #define LOCAL_GL_TANGENT_ARRAY_STRIDE_EXT                    0x843F
 #define LOCAL_GL_TANGENT_ARRAY_TYPE_EXT                      0x843E
+#define LOCAL_GL_TASK_SHADER_BIT_NV                          0x00000080
+#define LOCAL_GL_TASK_SHADER_NV                              0x955A
+#define LOCAL_GL_TASK_SUBROUTINE_NV                          0x957D
+#define LOCAL_GL_TASK_SUBROUTINE_UNIFORM_NV                  0x957F
+#define LOCAL_GL_TASK_WORK_GROUP_SIZE_NV                     0x953F
 #define LOCAL_GL_TERMINATE_SEQUENCE_COMMAND_NV               0x0000
 #define LOCAL_GL_TESSELLATION_FACTOR_AMD                     0x9005
 #define LOCAL_GL_TESSELLATION_MODE_AMD                       0x9004
 #define LOCAL_GL_TESS_CONTROL_OUTPUT_VERTICES                0x8E75
 #define LOCAL_GL_TESS_CONTROL_OUTPUT_VERTICES_EXT            0x8E75
 #define LOCAL_GL_TESS_CONTROL_OUTPUT_VERTICES_OES            0x8E75
 #define LOCAL_GL_TESS_CONTROL_PROGRAM_NV                     0x891E
 #define LOCAL_GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV    0x8C74
 #define LOCAL_GL_TESS_CONTROL_SHADER                         0x8E88
 #define LOCAL_GL_TESS_CONTROL_SHADER_BIT                     0x00000008
 #define LOCAL_GL_TESS_CONTROL_SHADER_BIT_EXT                 0x00000008
 #define LOCAL_GL_TESS_CONTROL_SHADER_BIT_OES                 0x00000008
 #define LOCAL_GL_TESS_CONTROL_SHADER_EXT                     0x8E88
 #define LOCAL_GL_TESS_CONTROL_SHADER_OES                     0x8E88
+#define LOCAL_GL_TESS_CONTROL_SHADER_PATCHES                 0x82F1
 #define LOCAL_GL_TESS_CONTROL_SHADER_PATCHES_ARB             0x82F1
 #define LOCAL_GL_TESS_CONTROL_SUBROUTINE                     0x92E9
 #define LOCAL_GL_TESS_CONTROL_SUBROUTINE_UNIFORM             0x92EF
 #define LOCAL_GL_TESS_CONTROL_TEXTURE                        0x829C
 #define LOCAL_GL_TESS_EVALUATION_PROGRAM_NV                  0x891F
 #define LOCAL_GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV 0x8C75
 #define LOCAL_GL_TESS_EVALUATION_SHADER                      0x8E87
 #define LOCAL_GL_TESS_EVALUATION_SHADER_BIT                  0x00000010
 #define LOCAL_GL_TESS_EVALUATION_SHADER_BIT_EXT              0x00000010
 #define LOCAL_GL_TESS_EVALUATION_SHADER_BIT_OES              0x00000010
 #define LOCAL_GL_TESS_EVALUATION_SHADER_EXT                  0x8E87
+#define LOCAL_GL_TESS_EVALUATION_SHADER_INVOCATIONS          0x82F2
 #define LOCAL_GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB      0x82F2
 #define LOCAL_GL_TESS_EVALUATION_SHADER_OES                  0x8E87
 #define LOCAL_GL_TESS_EVALUATION_SUBROUTINE                  0x92EA
 #define LOCAL_GL_TESS_EVALUATION_SUBROUTINE_UNIFORM          0x92F0
 #define LOCAL_GL_TESS_EVALUATION_TEXTURE                     0x829D
 #define LOCAL_GL_TESS_GEN_MODE                               0x8E76
 #define LOCAL_GL_TESS_GEN_MODE_EXT                           0x8E76
 #define LOCAL_GL_TESS_GEN_MODE_OES                           0x8E76
@@ -4969,16 +5103,21 @@
 #define LOCAL_GL_TEXTURE_FETCH_BARRIER_BIT                   0x00000008
 #define LOCAL_GL_TEXTURE_FETCH_BARRIER_BIT_EXT               0x00000008
 #define LOCAL_GL_TEXTURE_FILTER4_SIZE_SGIS                   0x8147
 #define LOCAL_GL_TEXTURE_FILTER_CONTROL                      0x8500
 #define LOCAL_GL_TEXTURE_FILTER_CONTROL_EXT                  0x8500
 #define LOCAL_GL_TEXTURE_FIXED_SAMPLE_LOCATIONS              0x9107
 #define LOCAL_GL_TEXTURE_FLOAT_COMPONENTS_NV                 0x888C
 #define LOCAL_GL_TEXTURE_FORMAT_QCOM                         0x8BD6
+#define LOCAL_GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT            0x8FBF
+#define LOCAL_GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM          0x8BFB
+#define LOCAL_GL_TEXTURE_FOVEATED_FEATURE_QUERY_QCOM         0x8BFD
+#define LOCAL_GL_TEXTURE_FOVEATED_MIN_PIXEL_DENSITY_QCOM     0x8BFC
+#define LOCAL_GL_TEXTURE_FOVEATED_NUM_FOCAL_POINTS_QUERY_QCOM        0x8BFE
 #define LOCAL_GL_TEXTURE_FREE_MEMORY_ATI                     0x87FC
 #define LOCAL_GL_TEXTURE_GATHER                              0x82A2
 #define LOCAL_GL_TEXTURE_GATHER_SHADOW                       0x82A3
 #define LOCAL_GL_TEXTURE_GEN_MODE                            0x2500
 #define LOCAL_GL_TEXTURE_GEN_MODE_OES                        0x2500
 #define LOCAL_GL_TEXTURE_GEN_Q                               0x0C63
 #define LOCAL_GL_TEXTURE_GEN_R                               0x0C62
 #define LOCAL_GL_TEXTURE_GEN_S                               0x0C60
@@ -5019,16 +5158,17 @@
 #define LOCAL_GL_TEXTURE_LUMINANCE_TYPE                      0x8C14
 #define LOCAL_GL_TEXTURE_LUMINANCE_TYPE_ARB                  0x8C14
 #define LOCAL_GL_TEXTURE_MAG_FILTER                          0x2800
 #define LOCAL_GL_TEXTURE_MAG_SIZE_NV                         0x871F
 #define LOCAL_GL_TEXTURE_MATERIAL_FACE_EXT                   0x8351
 #define LOCAL_GL_TEXTURE_MATERIAL_PARAMETER_EXT              0x8352
 #define LOCAL_GL_TEXTURE_MATRIX                              0x0BA8
 #define LOCAL_GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES        0x898F
+#define LOCAL_GL_TEXTURE_MAX_ANISOTROPY                      0x84FE
 #define LOCAL_GL_TEXTURE_MAX_ANISOTROPY_EXT                  0x84FE
 #define LOCAL_GL_TEXTURE_MAX_CLAMP_R_SGIX                    0x836B
 #define LOCAL_GL_TEXTURE_MAX_CLAMP_S_SGIX                    0x8369
 #define LOCAL_GL_TEXTURE_MAX_CLAMP_T_SGIX                    0x836A
 #define LOCAL_GL_TEXTURE_MAX_LEVEL                           0x813D
 #define LOCAL_GL_TEXTURE_MAX_LEVEL_APPLE                     0x813D
 #define LOCAL_GL_TEXTURE_MAX_LEVEL_SGIS                      0x813D
 #define LOCAL_GL_TEXTURE_MAX_LOD                             0x813B
@@ -5047,16 +5187,17 @@
 #define LOCAL_GL_TEXTURE_PRIORITY_EXT                        0x8066
 #define LOCAL_GL_TEXTURE_PROTECTED_EXT                       0x8BFA
 #define LOCAL_GL_TEXTURE_RANGE_LENGTH_APPLE                  0x85B7
 #define LOCAL_GL_TEXTURE_RANGE_POINTER_APPLE                 0x85B8
 #define LOCAL_GL_TEXTURE_RECTANGLE                           0x84F5
 #define LOCAL_GL_TEXTURE_RECTANGLE_ARB                       0x84F5
 #define LOCAL_GL_TEXTURE_RECTANGLE_NV                        0x84F5
 #define LOCAL_GL_TEXTURE_REDUCTION_MODE_ARB                  0x9366
+#define LOCAL_GL_TEXTURE_REDUCTION_MODE_EXT                  0x9366
 #define LOCAL_GL_TEXTURE_RED_SIZE                            0x805C
 #define LOCAL_GL_TEXTURE_RED_SIZE_EXT                        0x805C
 #define LOCAL_GL_TEXTURE_RED_TYPE                            0x8C10
 #define LOCAL_GL_TEXTURE_RED_TYPE_ARB                        0x8C10
 #define LOCAL_GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV  0x8E54
 #define LOCAL_GL_TEXTURE_RENDERBUFFER_NV                     0x8E55
 #define LOCAL_GL_TEXTURE_RESIDENT                            0x8067
 #define LOCAL_GL_TEXTURE_RESIDENT_EXT                        0x8067
@@ -5110,16 +5251,19 @@
 #define LOCAL_GL_TEXTURE_WIDTH_QCOM                          0x8BD2
 #define LOCAL_GL_TEXTURE_WRAP_Q_SGIS                         0x8137
 #define LOCAL_GL_TEXTURE_WRAP_R                              0x8072
 #define LOCAL_GL_TEXTURE_WRAP_R_EXT                          0x8072
 #define LOCAL_GL_TEXTURE_WRAP_R_OES                          0x8072
 #define LOCAL_GL_TEXTURE_WRAP_S                              0x2802
 #define LOCAL_GL_TEXTURE_WRAP_T                              0x2803
 #define LOCAL_GL_TEXT_FRAGMENT_SHADER_ATI                    0x8200
+#define LOCAL_GL_TILE_RASTER_ORDER_FIXED_MESA                0x8BB8
+#define LOCAL_GL_TILE_RASTER_ORDER_INCREASING_X_MESA         0x8BB9
+#define LOCAL_GL_TILE_RASTER_ORDER_INCREASING_Y_MESA         0x8BBA
 #define LOCAL_GL_TILING_TYPES_EXT                            0x9583
 #define LOCAL_GL_TIMEOUT_EXPIRED                             0x911B
 #define LOCAL_GL_TIMEOUT_EXPIRED_APPLE                       0x911B
 #define LOCAL_GL_TIMEOUT_IGNORED                             0xFFFFFFFFFFFFFFFF
 #define LOCAL_GL_TIMEOUT_IGNORED_APPLE                       0xFFFFFFFFFFFFFFFF
 #define LOCAL_GL_TIMESTAMP                                   0x8E28
 #define LOCAL_GL_TIMESTAMP_EXT                               0x8E28
 #define LOCAL_GL_TIME_ELAPSED                                0x88BF
@@ -5162,22 +5306,24 @@
 #define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_SIZE              0x8C85
 #define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT          0x8C85
 #define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV           0x8C85
 #define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_START             0x8C84
 #define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT         0x8C84
 #define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_START_NV          0x8C84
 #define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE            0x934C
 #define LOCAL_GL_TRANSFORM_FEEDBACK_NV                       0x8E22
+#define LOCAL_GL_TRANSFORM_FEEDBACK_OVERFLOW                 0x82EC
 #define LOCAL_GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB             0x82EC
 #define LOCAL_GL_TRANSFORM_FEEDBACK_PAUSED                   0x8E23
 #define LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN       0x8C88
 #define LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT   0x8C88
 #define LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV    0x8C88
 #define LOCAL_GL_TRANSFORM_FEEDBACK_RECORD_NV                0x8C86
+#define LOCAL_GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW          0x82ED
 #define LOCAL_GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB      0x82ED
 #define LOCAL_GL_TRANSFORM_FEEDBACK_VARYING                  0x92F4
 #define LOCAL_GL_TRANSFORM_FEEDBACK_VARYINGS                 0x8C83
 #define LOCAL_GL_TRANSFORM_FEEDBACK_VARYINGS_EXT             0x8C83
 #define LOCAL_GL_TRANSFORM_FEEDBACK_VARYINGS_NV              0x8C83
 #define LOCAL_GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH       0x8C76
 #define LOCAL_GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT   0x8C76
 #define LOCAL_GL_TRANSFORM_HINT_APPLE                        0x85B1
@@ -5231,16 +5377,18 @@
 #define LOCAL_GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES        0x8A43
 #define LOCAL_GL_UNIFORM_BLOCK_BINDING                       0x8A3F
 #define LOCAL_GL_UNIFORM_BLOCK_DATA_SIZE                     0x8A40
 #define LOCAL_GL_UNIFORM_BLOCK_INDEX                         0x8A3A
 #define LOCAL_GL_UNIFORM_BLOCK_NAME_LENGTH                   0x8A41
 #define LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER  0x90EC
 #define LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46
 #define LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45
+#define LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_MESH_SHADER_NV  0x959C
+#define LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_TASK_SHADER_NV  0x959D
 #define LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER     0x84F0
 #define LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER  0x84F1
 #define LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER   0x8A44
 #define LOCAL_GL_UNIFORM_BUFFER                              0x8A11
 #define LOCAL_GL_UNIFORM_BUFFER_ADDRESS_NV                   0x936F
 #define LOCAL_GL_UNIFORM_BUFFER_BINDING                      0x8A28
 #define LOCAL_GL_UNIFORM_BUFFER_BINDING_EXT                  0x8DEF
 #define LOCAL_GL_UNIFORM_BUFFER_EXT                          0x8DEE
@@ -5415,16 +5563,17 @@
 #define LOCAL_GL_UNSIGNED_SHORT_5_6_5_EXT                    0x8363
 #define LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV                    0x8364
 #define LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV_EXT                0x8364
 #define LOCAL_GL_UNSIGNED_SHORT_8_8_APPLE                    0x85BA
 #define LOCAL_GL_UNSIGNED_SHORT_8_8_MESA                     0x85BA
 #define LOCAL_GL_UNSIGNED_SHORT_8_8_REV_APPLE                0x85BB
 #define LOCAL_GL_UNSIGNED_SHORT_8_8_REV_MESA                 0x85BB
 #define LOCAL_GL_UPPER_LEFT                                  0x8CA2
+#define LOCAL_GL_UPPER_LEFT_EXT                              0x8CA2
 #define LOCAL_GL_USE_MISSING_GLYPH_NV                        0x90AA
 #define LOCAL_GL_UTF16_NV                                    0x909B
 #define LOCAL_GL_UTF8_NV                                     0x909A
 #define LOCAL_GL_UUID_SIZE_EXT                               16
 #define LOCAL_GL_V2F                                         0x2A20
 #define LOCAL_GL_V3F                                         0x2A21
 #define LOCAL_GL_VALIDATE_STATUS                             0x8B83
 #define LOCAL_GL_VARIABLE_A_NV                               0x8523
@@ -5568,16 +5717,17 @@
 #define LOCAL_GL_VERTEX_SHADER                               0x8B31
 #define LOCAL_GL_VERTEX_SHADER_ARB                           0x8B31
 #define LOCAL_GL_VERTEX_SHADER_BINDING_EXT                   0x8781
 #define LOCAL_GL_VERTEX_SHADER_BIT                           0x00000001
 #define LOCAL_GL_VERTEX_SHADER_BIT_EXT                       0x00000001
 #define LOCAL_GL_VERTEX_SHADER_EXT                           0x8780
 #define LOCAL_GL_VERTEX_SHADER_INSTRUCTIONS_EXT              0x87CF
 #define LOCAL_GL_VERTEX_SHADER_INVARIANTS_EXT                0x87D1
+#define LOCAL_GL_VERTEX_SHADER_INVOCATIONS                   0x82F0
 #define LOCAL_GL_VERTEX_SHADER_INVOCATIONS_ARB               0x82F0
 #define LOCAL_GL_VERTEX_SHADER_LOCALS_EXT                    0x87D3
 #define LOCAL_GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT           0x87D2
 #define LOCAL_GL_VERTEX_SHADER_OPTIMIZED_EXT                 0x87D4
 #define LOCAL_GL_VERTEX_SHADER_VARIANTS_EXT                  0x87D0
 #define LOCAL_GL_VERTEX_SOURCE_ATI                           0x8774
 #define LOCAL_GL_VERTEX_STATE_PROGRAM_NV                     0x8621
 #define LOCAL_GL_VERTEX_STREAM0_ATI                          0x876C
@@ -5593,16 +5743,17 @@
 #define LOCAL_GL_VERTEX_TEXTURE                              0x829B
 #define LOCAL_GL_VERTEX_WEIGHTING_EXT                        0x8509
 #define LOCAL_GL_VERTEX_WEIGHT_ARRAY_EXT                     0x850C
 #define LOCAL_GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT             0x8510
 #define LOCAL_GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT                0x850D
 #define LOCAL_GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT              0x850F
 #define LOCAL_GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT                0x850E
 #define LOCAL_GL_VERTICAL_LINE_TO_NV                         0x08
+#define LOCAL_GL_VERTICES_SUBMITTED                          0x82EE
 #define LOCAL_GL_VERTICES_SUBMITTED_ARB                      0x82EE
 #define LOCAL_GL_VIBRANCE_BIAS_NV                            0x8719
 #define LOCAL_GL_VIBRANCE_SCALE_NV                           0x8713
 #define LOCAL_GL_VIDEO_BUFFER_BINDING_NV                     0x9021
 #define LOCAL_GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV             0x902D
 #define LOCAL_GL_VIDEO_BUFFER_NV                             0x9020
 #define LOCAL_GL_VIDEO_BUFFER_PITCH_NV                       0x9028
 #define LOCAL_GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV         0x903B
@@ -5675,16 +5826,17 @@
 #define LOCAL_GL_VIRTUAL_PAGE_SIZE_Z_EXT                     0x9197
 #define LOCAL_GL_VIVIDLIGHT_NV                               0x92A6
 #define LOCAL_GL_VOLATILE_APPLE                              0x8A1A
 #define LOCAL_GL_WAIT_FAILED                                 0x911D
 #define LOCAL_GL_WAIT_FAILED_APPLE                           0x911D
 #define LOCAL_GL_WARPS_PER_SM_NV                             0x933A
 #define LOCAL_GL_WARP_SIZE_NV                                0x9339
 #define LOCAL_GL_WEIGHTED_AVERAGE_ARB                        0x9367
+#define LOCAL_GL_WEIGHTED_AVERAGE_EXT                        0x9367
 #define LOCAL_GL_WEIGHT_ARRAY_ARB                            0x86AD
 #define LOCAL_GL_WEIGHT_ARRAY_BUFFER_BINDING                 0x889E
 #define LOCAL_GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB             0x889E
 #define LOCAL_GL_WEIGHT_ARRAY_BUFFER_BINDING_OES             0x889E
 #define LOCAL_GL_WEIGHT_ARRAY_OES                            0x86AD
 #define LOCAL_GL_WEIGHT_ARRAY_POINTER_ARB                    0x86AC
 #define LOCAL_GL_WEIGHT_ARRAY_POINTER_OES                    0x86AC
 #define LOCAL_GL_WEIGHT_ARRAY_SIZE_ARB                       0x86AB
@@ -5723,16 +5875,17 @@
 #define LOCAL_GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV    0x9036
 #define LOCAL_GL_Z4Y12Z4CB12Z4CR12_444_NV                    0x9037
 #define LOCAL_GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV               0x9035
 #define LOCAL_GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV    0x9034
 #define LOCAL_GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV               0x9033
 #define LOCAL_GL_ZERO                                        0
 #define LOCAL_GL_ZERO_EXT                                    0x87DD
 #define LOCAL_GL_ZERO_TO_ONE                                 0x935F
+#define LOCAL_GL_ZERO_TO_ONE_EXT                             0x935F
 #define LOCAL_GL_ZOOM_X                                      0x0D16
 #define LOCAL_GL_ZOOM_Y                                      0x0D17
 #define LOCAL_GL_Z_EXT                                       0x87D7
 
 
 // EGL
 #define LOCAL_EGL_ALPHA_FORMAT                               0x3088
 #define LOCAL_EGL_ALPHA_FORMAT_NONPRE                        0x308B
@@ -5787,16 +5940,20 @@
 #define LOCAL_EGL_COLOR_ARGB_HI                              0x8F73
 #define LOCAL_EGL_COLOR_BUFFER_TYPE                          0x303F
 #define LOCAL_EGL_COLOR_COMPONENT_TYPE_EXT                   0x3339
 #define LOCAL_EGL_COLOR_COMPONENT_TYPE_FIXED_EXT             0x333A
 #define LOCAL_EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT             0x333B
 #define LOCAL_EGL_COLOR_FORMAT_HI                            0x8F70
 #define LOCAL_EGL_COLOR_RGBA_HI                              0x8F72
 #define LOCAL_EGL_COLOR_RGB_HI                               0x8F71
+#define LOCAL_EGL_COMPOSITE_DEADLINE_ANDROID                 0x3431
+#define LOCAL_EGL_COMPOSITE_INTERVAL_ANDROID                 0x3432
+#define LOCAL_EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID       0x3433
+#define LOCAL_EGL_COMPOSITION_LATCH_TIME_ANDROID             0x3436
 #define LOCAL_EGL_COMPOSITOR_DROP_NEWEST_FRAME_EXT           0x3462
 #define LOCAL_EGL_COMPOSITOR_KEEP_NEWEST_FRAME_EXT           0x3463
 #define LOCAL_EGL_CONDITION_SATISFIED                        0x30F6
 #define LOCAL_EGL_CONDITION_SATISFIED_KHR                    0x30F6
 #define LOCAL_EGL_CONDITION_SATISFIED_NV                     0x30EC
 #define LOCAL_EGL_CONFIG_CAVEAT                              0x3027
 #define LOCAL_EGL_CONFIG_ID                                  0x3028
 #define LOCAL_EGL_CONFORMANT                                 0x3042
@@ -5830,16 +5987,17 @@
 #define LOCAL_EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR     0x31BD
 #define LOCAL_EGL_CONTEXT_OPENGL_ROBUST_ACCESS               0x31B2
 #define LOCAL_EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR       0x00000004
 #define LOCAL_EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT           0x30BF
 #define LOCAL_EGL_CONTEXT_PRIORITY_HIGH_IMG                  0x3101
 #define LOCAL_EGL_CONTEXT_PRIORITY_LEVEL_IMG                 0x3100
 #define LOCAL_EGL_CONTEXT_PRIORITY_LOW_IMG                   0x3103
 #define LOCAL_EGL_CONTEXT_PRIORITY_MEDIUM_IMG                0x3102
+#define LOCAL_EGL_CONTEXT_PRIORITY_REALTIME_NV               0x3357
 #define LOCAL_EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR         0x2098
 #define LOCAL_EGL_CONTEXT_RELEASE_BEHAVIOR_KHR               0x2097
 #define LOCAL_EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR          0
 #define LOCAL_EGL_CORE_NATIVE_ENGINE                         0x305B
 #define LOCAL_EGL_COVERAGE_BUFFERS_NV                        0x30E0
 #define LOCAL_EGL_COVERAGE_SAMPLES_NV                        0x30E1
 #define LOCAL_EGL_COVERAGE_SAMPLE_RESOLVE_DEFAULT_NV         0x3132
 #define LOCAL_EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV            0x3133
@@ -5856,18 +6014,20 @@
 #define LOCAL_EGL_DEBUG_MSG_ERROR_KHR                        0x33BA
 #define LOCAL_EGL_DEBUG_MSG_INFO_KHR                         0x33BC
 #define LOCAL_EGL_DEBUG_MSG_WARN_KHR                         0x33BB
 #define LOCAL_EGL_DEFAULT_DISPLAY                            EGL_CAST(EGLNativeDisplayType,0)
 #define LOCAL_EGL_DEPTH_ENCODING_NONE_NV                     0
 #define LOCAL_EGL_DEPTH_ENCODING_NONLINEAR_NV                0x30E3
 #define LOCAL_EGL_DEPTH_ENCODING_NV                          0x30E2
 #define LOCAL_EGL_DEPTH_SIZE                                 0x3025
+#define LOCAL_EGL_DEQUEUE_READY_TIME_ANDROID                 0x343B
 #define LOCAL_EGL_DEVICE_EXT                                 0x322C
 #define LOCAL_EGL_DISCARD_SAMPLES_ARM                        0x3286
+#define LOCAL_EGL_DISPLAY_PRESENT_TIME_ANDROID               0x343A
 #define LOCAL_EGL_DISPLAY_SCALING                            10000
 #define LOCAL_EGL_DMA_BUF_PLANE0_FD_EXT                      0x3272
 #define LOCAL_EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT             0x3444
 #define LOCAL_EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT             0x3443
 #define LOCAL_EGL_DMA_BUF_PLANE0_OFFSET_EXT                  0x3273
 #define LOCAL_EGL_DMA_BUF_PLANE0_PITCH_EXT                   0x3274
 #define LOCAL_EGL_DMA_BUF_PLANE1_FD_EXT                      0x3275
 #define LOCAL_EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT             0x3446
@@ -5885,45 +6045,51 @@
 #define LOCAL_EGL_DMA_BUF_PLANE3_OFFSET_EXT                  0x3441
 #define LOCAL_EGL_DMA_BUF_PLANE3_PITCH_EXT                   0x3442
 #define LOCAL_EGL_DONT_CARE                                  EGL_CAST(EGLint,-1)
 #define LOCAL_EGL_DRAW                                       0x3059
 #define LOCAL_EGL_DRM_BUFFER_FORMAT_ARGB32_MESA              0x31D2
 #define LOCAL_EGL_DRM_BUFFER_FORMAT_MESA                     0x31D0
 #define LOCAL_EGL_DRM_BUFFER_MESA                            0x31D3
 #define LOCAL_EGL_DRM_BUFFER_STRIDE_MESA                     0x31D4
+#define LOCAL_EGL_DRM_BUFFER_USE_CURSOR_MESA                 0x00000004
 #define LOCAL_EGL_DRM_BUFFER_USE_MESA                        0x31D1
 #define LOCAL_EGL_DRM_BUFFER_USE_SCANOUT_MESA                0x00000001
 #define LOCAL_EGL_DRM_BUFFER_USE_SHARE_MESA                  0x00000002
 #define LOCAL_EGL_DRM_CONNECTOR_EXT                          0x3236
 #define LOCAL_EGL_DRM_CRTC_EXT                               0x3234
 #define LOCAL_EGL_DRM_DEVICE_FILE_EXT                        0x3233
 #define LOCAL_EGL_DRM_PLANE_EXT                              0x3235
 #define LOCAL_EGL_EXTENSIONS                                 0x3055
 #define LOCAL_EGL_EXTERNAL_REF_ID_EXT                        0x3461
 #define LOCAL_EGL_FALSE                                      0
+#define LOCAL_EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID        0x3439
+#define LOCAL_EGL_FIRST_COMPOSITION_START_TIME_ANDROID       0x3437
 #define LOCAL_EGL_FIXED_SIZE_ANGLE                           0x3201
 #define LOCAL_EGL_FOREVER                                    0xFFFFFFFFFFFFFFFF
 #define LOCAL_EGL_FOREVER_KHR                                0xFFFFFFFFFFFFFFFF
 #define LOCAL_EGL_FOREVER_NV                                 0xFFFFFFFFFFFFFFFF
 #define LOCAL_EGL_FORMAT_RGBA_8888_EXACT_KHR                 0x30C2
 #define LOCAL_EGL_FORMAT_RGBA_8888_KHR                       0x30C3
 #define LOCAL_EGL_FORMAT_RGB_565_EXACT_KHR                   0x30C0
 #define LOCAL_EGL_FORMAT_RGB_565_KHR                         0x30C1
 #define LOCAL_EGL_FRAMEBUFFER_TARGET_ANDROID                 0x3147
 #define LOCAL_EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID          0x314C
+#define LOCAL_EGL_FRONT_BUFFER_EXT                           0x3464
 #define LOCAL_EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV    0x334C
 #define LOCAL_EGL_GL_COLORSPACE                              0x309D
 #define LOCAL_EGL_GL_COLORSPACE_BT2020_LINEAR_EXT            0x333F
 #define LOCAL_EGL_GL_COLORSPACE_BT2020_PQ_EXT                0x3340
+#define LOCAL_EGL_GL_COLORSPACE_DEFAULT_EXT                  0x314D
 #define LOCAL_EGL_GL_COLORSPACE_DISPLAY_P3_EXT               0x3363
 #define LOCAL_EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT        0x3362
 #define LOCAL_EGL_GL_COLORSPACE_KHR                          0x309D
 #define LOCAL_EGL_GL_COLORSPACE_LINEAR                       0x308A
 #define LOCAL_EGL_GL_COLORSPACE_LINEAR_KHR                   0x308A
+#define LOCAL_EGL_GL_COLORSPACE_SCRGB_EXT                    0x3351
 #define LOCAL_EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT             0x3350
 #define LOCAL_EGL_GL_COLORSPACE_SRGB                         0x3089
 #define LOCAL_EGL_GL_COLORSPACE_SRGB_KHR                     0x3089
 #define LOCAL_EGL_GL_RENDERBUFFER                            0x30B9
 #define LOCAL_EGL_GL_RENDERBUFFER_KHR                        0x30B9
 #define LOCAL_EGL_GL_TEXTURE_2D                              0x30B1
 #define LOCAL_EGL_GL_TEXTURE_2D_KHR                          0x30B1
 #define LOCAL_EGL_GL_TEXTURE_3D                              0x30B2
@@ -5944,21 +6110,25 @@
 #define LOCAL_EGL_GL_TEXTURE_LEVEL_KHR                       0x30BC
 #define LOCAL_EGL_GL_TEXTURE_ZOFFSET                         0x30BD
 #define LOCAL_EGL_GL_TEXTURE_ZOFFSET_KHR                     0x30BD
 #define LOCAL_EGL_GREEN_SIZE                                 0x3023
 #define LOCAL_EGL_HEIGHT                                     0x3056
 #define LOCAL_EGL_HORIZONTAL_RESOLUTION                      0x3090
 #define LOCAL_EGL_IMAGE_PRESERVED                            0x30D2
 #define LOCAL_EGL_IMAGE_PRESERVED_KHR                        0x30D2
+#define LOCAL_EGL_IMPORT_EXPLICIT_SYNC_EXT                   0x3472
+#define LOCAL_EGL_IMPORT_IMPLICIT_SYNC_EXT                   0x3471
+#define LOCAL_EGL_IMPORT_SYNC_TYPE_EXT                       0x3470
 #define LOCAL_EGL_INTEROP_BIT_KHR                            0x0010
 #define LOCAL_EGL_ITU_REC2020_EXT                            0x3281
 #define LOCAL_EGL_ITU_REC601_EXT                             0x327F
 #define LOCAL_EGL_ITU_REC709_EXT                             0x3280
 #define LOCAL_EGL_LARGEST_PBUFFER                            0x3058
+#define LOCAL_EGL_LAST_COMPOSITION_START_TIME_ANDROID        0x3438
 #define LOCAL_EGL_LEVEL                                      0x3029
 #define LOCAL_EGL_LINUX_DMA_BUF_EXT                          0x3270
 #define LOCAL_EGL_LINUX_DRM_FOURCC_EXT                       0x3271
 #define LOCAL_EGL_LOCK_SURFACE_BIT_KHR                       0x0080
 #define LOCAL_EGL_LOCK_USAGE_HINT_KHR                        0x30C5
 #define LOCAL_EGL_LOSE_CONTEXT_ON_RESET                      0x31BF
 #define LOCAL_EGL_LOSE_CONTEXT_ON_RESET_EXT                  0x31BF
 #define LOCAL_EGL_LOSE_CONTEXT_ON_RESET_KHR                  0x31BF
@@ -6070,21 +6240,24 @@
 #define LOCAL_EGL_PLATFORM_X11_SCREEN_KHR                    0x31D6
 #define LOCAL_EGL_POST_SUB_BUFFER_SUPPORTED_NV               0x30BE
 #define LOCAL_EGL_PRIMARY_COMPOSITOR_CONTEXT_EXT             0x3460
 #define LOCAL_EGL_PRODUCER_FRAME_KHR                         0x3212
 #define LOCAL_EGL_PRODUCER_MAX_FRAME_HINT_NV                 0x3337
 #define LOCAL_EGL_PRODUCER_METADATA_NV                       0x3253
 #define LOCAL_EGL_PROTECTED_CONTENT_EXT                      0x32C0
 #define LOCAL_EGL_READ                                       0x305A
+#define LOCAL_EGL_READS_DONE_TIME_ANDROID                    0x343C
 #define LOCAL_EGL_READ_SURFACE_BIT_KHR                       0x0001
 #define LOCAL_EGL_RECORDABLE_ANDROID                         0x3142
 #define LOCAL_EGL_RED_SIZE                                   0x3024
 #define LOCAL_EGL_RENDERABLE_TYPE                            0x3040
+#define LOCAL_EGL_RENDERING_COMPLETE_TIME_ANDROID            0x3435
 #define LOCAL_EGL_RENDER_BUFFER                              0x3086
+#define LOCAL_EGL_REQUESTED_PRESENT_TIME_ANDROID             0x3434
 #define LOCAL_EGL_RGB_BUFFER                                 0x308E
 #define LOCAL_EGL_SAMPLES                                    0x3031
 #define LOCAL_EGL_SAMPLE_BUFFERS                             0x3032
 #define LOCAL_EGL_SAMPLE_RANGE_HINT_EXT                      0x327C
 #define LOCAL_EGL_SHARED_IMAGE_NOK                           0x30DA
 #define LOCAL_EGL_SIGNALED                                   0x30F2
 #define LOCAL_EGL_SIGNALED_KHR                               0x30F2
 #define LOCAL_EGL_SIGNALED_NV                                0x30E8
@@ -6135,16 +6308,18 @@
 #define LOCAL_EGL_STREAM_TYPE_NV                             0x3241
 #define LOCAL_EGL_SUCCESS                                    0x3000
 #define LOCAL_EGL_SUPPORT_RESET_NV                           0x3334
 #define LOCAL_EGL_SUPPORT_REUSE_NV                           0x3335
 #define LOCAL_EGL_SURFACE_TYPE                               0x3033
 #define LOCAL_EGL_SWAP_BEHAVIOR                              0x3093
 #define LOCAL_EGL_SWAP_BEHAVIOR_PRESERVED_BIT                0x0400
 #define LOCAL_EGL_SWAP_INTERVAL_EXT                          0x322F
+#define LOCAL_EGL_SYNC_CLIENT_EXT                            0x3364
+#define LOCAL_EGL_SYNC_CLIENT_SIGNAL_EXT                     0x3365
 #define LOCAL_EGL_SYNC_CL_EVENT                              0x30FE
 #define LOCAL_EGL_SYNC_CL_EVENT_COMPLETE                     0x30FF
 #define LOCAL_EGL_SYNC_CL_EVENT_COMPLETE_KHR                 0x30FF
 #define LOCAL_EGL_SYNC_CL_EVENT_KHR                          0x30FE
 #define LOCAL_EGL_SYNC_CONDITION                             0x30F8
 #define LOCAL_EGL_SYNC_CONDITION_KHR                         0x30F8
 #define LOCAL_EGL_SYNC_CONDITION_NV                          0x30EE
 #define LOCAL_EGL_SYNC_CUDA_EVENT_COMPLETE_NV                0x323D
@@ -6173,16 +6348,19 @@
 #define LOCAL_EGL_TEXTURE_2D                                 0x305F
 #define LOCAL_EGL_TEXTURE_FORMAT                             0x3080
 #define LOCAL_EGL_TEXTURE_RGB                                0x305D
 #define LOCAL_EGL_TEXTURE_RGBA                               0x305E
 #define LOCAL_EGL_TEXTURE_TARGET                             0x3081
 #define LOCAL_EGL_TIMEOUT_EXPIRED                            0x30F5
 #define LOCAL_EGL_TIMEOUT_EXPIRED_KHR                        0x30F5
 #define LOCAL_EGL_TIMEOUT_EXPIRED_NV                         0x30EB
+#define LOCAL_EGL_TIMESTAMPS_ANDROID                         0x3430
+#define LOCAL_EGL_TIMESTAMP_INVALID_ANDROID                  EGL_CAST(EGLnsecsANDROID,-1)
+#define LOCAL_EGL_TIMESTAMP_PENDING_ANDROID                  EGL_CAST(EGLnsecsANDROID,-2)
 #define LOCAL_EGL_TRACK_REFERENCES_KHR                       0x3352
 #define LOCAL_EGL_TRANSPARENT_BLUE_VALUE                     0x3035
 #define LOCAL_EGL_TRANSPARENT_GREEN_VALUE                    0x3036
 #define LOCAL_EGL_TRANSPARENT_RED_VALUE                      0x3037
 #define LOCAL_EGL_TRANSPARENT_RGB                            0x3052
 #define LOCAL_EGL_TRANSPARENT_TYPE                           0x3034
 #define LOCAL_EGL_TRUE                                       1
 #define LOCAL_EGL_UNKNOWN                                    EGL_CAST(EGLint,-1)
@@ -6580,17 +6758,17 @@
 #define LOCAL_WGL_BIND_TO_TEXTURE_RGB_ARB                    0x2070
 #define LOCAL_WGL_BIND_TO_VIDEO_RGBA_NV                      0x20C1
 #define LOCAL_WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV             0x20C2
 #define LOCAL_WGL_BIND_TO_VIDEO_RGB_NV                       0x20C0
 #define LOCAL_WGL_BLUE_BITS_ARB                              0x2019
 #define LOCAL_WGL_BLUE_BITS_EXT                              0x2019
 #define LOCAL_WGL_BLUE_SHIFT_ARB                             0x201A
 #define LOCAL_WGL_BLUE_SHIFT_EXT                             0x201A
-#define LOCAL_WGL_COLORSPACE_EXT                             0x3087
+#define LOCAL_WGL_COLORSPACE_EXT                             0x309D
 #define LOCAL_WGL_COLORSPACE_LINEAR_EXT                      0x308A
 #define LOCAL_WGL_COLORSPACE_SRGB_EXT                        0x3089
 #define LOCAL_WGL_COLOR_BITS_ARB                             0x2014
 #define LOCAL_WGL_COLOR_BITS_EXT                             0x2014
 #define LOCAL_WGL_COLOR_SAMPLES_NV                           0x20B9
 #define LOCAL_WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB      0x00000002
 #define LOCAL_WGL_CONTEXT_CORE_PROFILE_BIT_ARB               0x00000001
 #define LOCAL_WGL_CONTEXT_DEBUG_BIT_ARB                      0x00000001
@@ -6784,16 +6962,17 @@
 #define LOCAL_WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB            0x207F
 #define LOCAL_WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB            0x2081
 #define LOCAL_WGL_TEXTURE_DEPTH_COMPONENT_NV                 0x20A6
 #define LOCAL_WGL_TEXTURE_FLOAT_RGBA_NV                      0x20B8
 #define LOCAL_WGL_TEXTURE_FLOAT_RGB_NV                       0x20B7
 #define LOCAL_WGL_TEXTURE_FLOAT_RG_NV                        0x20B6
 #define LOCAL_WGL_TEXTURE_FLOAT_R_NV                         0x20B5
 #define LOCAL_WGL_TEXTURE_FORMAT_ARB                         0x2072
+#define LOCAL_WGL_TEXTURE_RECTANGLE_ATI                      0x21A5
 #define LOCAL_WGL_TEXTURE_RECTANGLE_NV                       0x20A2
 #define LOCAL_WGL_TEXTURE_RGBA_ARB                           0x2076
 #define LOCAL_WGL_TEXTURE_RGB_ARB                            0x2075
 #define LOCAL_WGL_TEXTURE_TARGET_ARB                         0x2073
 #define LOCAL_WGL_TRANSPARENT_ALPHA_VALUE_ARB                0x203A
 #define LOCAL_WGL_TRANSPARENT_ARB                            0x200A
 #define LOCAL_WGL_TRANSPARENT_BLUE_VALUE_ARB                 0x2039
 #define LOCAL_WGL_TRANSPARENT_EXT                            0x200A
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -106,16 +106,18 @@ static const char* const sExtensionNames
     "GL_ARB_pixel_buffer_object",
     "GL_ARB_robust_buffer_access_behavior",
     "GL_ARB_robustness",
     "GL_ARB_sampler_objects",
     "GL_ARB_seamless_cube_map",
     "GL_ARB_shader_texture_lod",
     "GL_ARB_sync",
     "GL_ARB_texture_compression",
+    "GL_ARB_texture_compression_bptc",
+    "GL_ARB_texture_compression_rgtc",
     "GL_ARB_texture_float",
     "GL_ARB_texture_non_power_of_two",
     "GL_ARB_texture_rectangle",
     "GL_ARB_texture_rg",
     "GL_ARB_texture_storage",
     "GL_ARB_texture_swizzle",
     "GL_ARB_timer_query",
     "GL_ARB_transform_feedback2",
@@ -141,17 +143,19 @@ static const char* const sExtensionNames
     "GL_EXT_occlusion_query_boolean",
     "GL_EXT_packed_depth_stencil",
     "GL_EXT_read_format_bgra",
     "GL_EXT_robustness",
     "GL_EXT_sRGB",
     "GL_EXT_sRGB_write_control",
     "GL_EXT_shader_texture_lod",
     "GL_EXT_texture3D",
+    "GL_EXT_texture_compression_bptc",
     "GL_EXT_texture_compression_dxt1",
+    "GL_EXT_texture_compression_rgtc",
     "GL_EXT_texture_compression_s3tc",
     "GL_EXT_texture_compression_s3tc_srgb",
     "GL_EXT_texture_filter_anisotropic",
     "GL_EXT_texture_format_BGRA8888",
     "GL_EXT_texture_sRGB",
     "GL_EXT_texture_storage",
     "GL_EXT_timer_query",
     "GL_EXT_transform_feedback",
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -127,16 +127,18 @@ enum class GLFeature {
     seamless_cube_map_opt_in,
     shader_texture_lod,
     split_framebuffer,
     standard_derivatives,
     sync,
     texture_3D,
     texture_3D_compressed,
     texture_3D_copy,
+    texture_compression_bptc,
+    texture_compression_rgtc,
     texture_float,
     texture_float_linear,
     texture_half_float,
     texture_half_float_linear,
     texture_non_power_of_two,
     texture_rg,
     texture_storage,
     texture_swizzle,
@@ -405,16 +407,18 @@ public:
         ARB_pixel_buffer_object,
         ARB_robust_buffer_access_behavior,
         ARB_robustness,
         ARB_sampler_objects,
         ARB_seamless_cube_map,
         ARB_shader_texture_lod,
         ARB_sync,
         ARB_texture_compression,
+        ARB_texture_compression_bptc,
+        ARB_texture_compression_rgtc,
         ARB_texture_float,
         ARB_texture_non_power_of_two,
         ARB_texture_rectangle,
         ARB_texture_rg,
         ARB_texture_storage,
         ARB_texture_swizzle,
         ARB_timer_query,
         ARB_transform_feedback2,
@@ -440,17 +444,19 @@ public:
         EXT_occlusion_query_boolean,
         EXT_packed_depth_stencil,
         EXT_read_format_bgra,
         EXT_robustness,
         EXT_sRGB,
         EXT_sRGB_write_control,
         EXT_shader_texture_lod,
         EXT_texture3D,
+        EXT_texture_compression_bptc,
         EXT_texture_compression_dxt1,
+        EXT_texture_compression_rgtc,
         EXT_texture_compression_s3tc,
         EXT_texture_compression_s3tc_srgb,
         EXT_texture_filter_anisotropic,
         EXT_texture_format_BGRA8888,
         EXT_texture_sRGB,
         EXT_texture_storage,
         EXT_timer_query,
         EXT_transform_feedback,
--- a/gfx/gl/GLContextFeatures.cpp
+++ b/gfx/gl/GLContextFeatures.cpp
@@ -649,16 +649,38 @@ static const FeatureInfo sFeatureInfoArr
         GLContext::Extension_None,
         {
             GLContext::EXT_copy_texture,
             GLContext::OES_texture_3D,
             GLContext::Extensions_End
         }
     },
     {
+        "texture_compression_bptc",
+        GLVersion::GL4_2,
+        GLESVersion::NONE,
+        GLContext::Extension_None,
+        {
+            GLContext::ARB_texture_compression_bptc,
+            GLContext::EXT_texture_compression_bptc,
+            GLContext::Extensions_End
+        }
+    },
+    {
+        "texture_compression_rgtc",
+        GLVersion::GL3,
+        GLESVersion::NONE,
+        GLContext::Extension_None,
+        {
+            GLContext::ARB_texture_compression_rgtc,
+            GLContext::EXT_texture_compression_rgtc,
+            GLContext::Extensions_End
+        }
+    },
+    {
         "texture_float",
         GLVersion::GL3,
         GLESVersion::ES3,
         GLContext::Extension_None,
         {
             GLContext::ARB_texture_float,
             GLContext::OES_texture_float,
             GLContext::Extensions_End
--- a/gfx/gl/GLParseRegistryXML.py
+++ b/gfx/gl/GLParseRegistryXML.py
@@ -1,11 +1,9 @@
-#!/usr/bin/env python
-# coding=utf8
-
+#!/usr/bin/env python2
 
 ################################################################################
 # TUTORIAL
 # This script will generate GLConsts.h
 #
 # Step 1:
 #   Download the last gl.xml, egl.xml, glx.xml and wgl.xml from
 #   http://www.opengl.org/registry/#specfiles into a directory of your choice
@@ -22,20 +20,25 @@
 ################################################################################
 
 # includes
 from __future__ import print_function
 import os
 import sys
 import xml.etree.ElementTree
 
+assert len(sys.argv) == 3, (
+       'Usage: ./GLParseRegistryXML.py path/to/OpenGL-Registry path/to/EGL-Registry')
+
+(_, GL_REGISTRY_PATH, EGL_REGISTRY_PATH) = sys.argv
 
 ################################################################################
 # export management
 
+
 class GLConstHeader:
     def __init__(self, f):
         self.f = f
 
     def write(self, arg):
         if isinstance(arg, list):
             self.f.write('\n'.join(arg) + '\n')
         elif isinstance(arg, (int, long)):
@@ -92,27 +95,16 @@ class GLConstHeader:
 
 ################################################################################
 # underground code
 
 def getScriptDir():
     return os.path.dirname(__file__) + '/'
 
 
-def getXMLDir():
-    if len(sys.argv) == 1:
-        return './'
-
-    dirPath = sys.argv[1]
-    if dirPath[-1] != '/':
-        dirPath += '/'
-
-    return dirPath
-
-
 class GLConst:
     def __init__(self, lib, name, value, type):
         self.lib = lib
         self.name = name
         self.value = value
         self.type = type
 
 
@@ -122,19 +114,17 @@ class GLDatabase:
 
     def __init__(self):
         self.consts = {}
         self.libs = set(GLDatabase.LIBS)
         self.vendors = set(['EXT', 'ATI'])
         # there is no vendor="EXT" and vendor="ATI" in gl.xml,
         # so we manualy declare them
 
-    def loadXML(self, path):
-        xmlPath = getXMLDir() + path
-
+    def loadXML(self, xmlPath):
         if not os.path.isfile(xmlPath):
             print('missing file "' + xmlPath + '"')
             return False
 
         tree = xml.etree.ElementTree.parse(xmlPath)
         root = tree.getroot()
 
         for enums in root.iter('enums'):
@@ -169,17 +159,17 @@ class GLDatabase:
                     # if no type specified, we get the namespace's default type
                     type = namespaceType
 
                 self.consts[lib + '_' + name] = GLConst(lib, name, value, type)
 
         return True
 
     def exportConsts(self, path):
-        with open(getScriptDir() + path, 'w') as f:
+        with open(getScriptDir() + path, 'wb') as f:
 
             headerFile = GLConstHeader(f)
             headerFile.formatFileBegin()
 
             constNames = self.consts.keys()
             constNames.sort()
 
             for lib in GLDatabase.LIBS:
@@ -195,15 +185,15 @@ class GLDatabase:
 
                 headerFile.formatLibEnd(lib)
 
             headerFile.formatFileEnd()
 
 
 glDatabase = GLDatabase()
 
-success = glDatabase.loadXML('gl.xml')
-success = success and glDatabase.loadXML('egl.xml')
-success = success and glDatabase.loadXML('glx.xml')
-success = success and glDatabase.loadXML('wgl.xml')
+success = glDatabase.loadXML(GL_REGISTRY_PATH + '/xml/gl.xml')
+success = success and glDatabase.loadXML(GL_REGISTRY_PATH + '/xml/glx.xml')
+success = success and glDatabase.loadXML(GL_REGISTRY_PATH + '/xml/wgl.xml')
+success = success and glDatabase.loadXML(EGL_REGISTRY_PATH + '/api/egl.xml')
 
 if success:
     glDatabase.exportConsts('GLConsts.h')
--- a/js/src/gc/GC.cpp
+++ b/js/src/gc/GC.cpp
@@ -283,53 +283,53 @@ namespace TuningDefaults {
 
     /* JSGC_ALLOCATION_THRESHOLD */
     static const size_t GCZoneAllocThresholdBase = 30 * 1024 * 1024;
 
     /* JSGC_MAX_MALLOC_BYTES */
     static const size_t MaxMallocBytes = 128 * 1024 * 1024;
 
     /* JSGC_ALLOCATION_THRESHOLD_FACTOR */
-    static const double AllocThresholdFactor = 0.9;
+    static const float AllocThresholdFactor = 0.9f;
 
     /* JSGC_ALLOCATION_THRESHOLD_FACTOR_AVOID_INTERRUPT */
-    static const double AllocThresholdFactorAvoidInterrupt = 0.9;
+    static const float AllocThresholdFactorAvoidInterrupt = 0.9f;
 
     /* no parameter */
-    static const double MallocThresholdGrowFactor = 1.5;
+    static const float MallocThresholdGrowFactor = 1.5f;
 
     /* no parameter */
-    static const double MallocThresholdShrinkFactor = 0.9;
+    static const float MallocThresholdShrinkFactor = 0.9f;
 
     /* no parameter */
     static const size_t MallocThresholdLimit = 1024 * 1024 * 1024;
 
     /* no parameter */
     static const size_t ZoneAllocDelayBytes = 1024 * 1024;
 
     /* JSGC_DYNAMIC_HEAP_GROWTH */
     static const bool DynamicHeapGrowthEnabled = false;
 
     /* JSGC_HIGH_FREQUENCY_TIME_LIMIT */
     static const auto HighFrequencyThreshold = 1; // in seconds
 
     /* JSGC_HIGH_FREQUENCY_LOW_LIMIT */
-    static const uint64_t HighFrequencyLowLimitBytes = 100 * 1024 * 1024;
+    static const size_t HighFrequencyLowLimitBytes = 100 * 1024 * 1024;
 
     /* JSGC_HIGH_FREQUENCY_HIGH_LIMIT */
-    static const uint64_t HighFrequencyHighLimitBytes = 500 * 1024 * 1024;
+    static const size_t HighFrequencyHighLimitBytes = 500 * 1024 * 1024;
 
     /* JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX */
-    static const double HighFrequencyHeapGrowthMax = 3.0;
+    static const float HighFrequencyHeapGrowthMax = 3.0f;
 
     /* JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN */
-    static const double HighFrequencyHeapGrowthMin = 1.5;
+    static const float HighFrequencyHeapGrowthMin = 1.5f;
 
     /* JSGC_LOW_FREQUENCY_HEAP_GROWTH */
-    static const double LowFrequencyHeapGrowth = 1.5;
+    static const float LowFrequencyHeapGrowth = 1.5f;
 
     /* JSGC_DYNAMIC_MARK_SLICE */
     static const bool DynamicMarkSliceEnabled = false;
 
     /* JSGC_MIN_EMPTY_CHUNK_COUNT */
     static const uint32_t MinEmptyChunkCount = 1;
 
     /* JSGC_MAX_EMPTY_CHUNK_COUNT */
@@ -351,34 +351,34 @@ namespace TuningDefaults {
 }}} // namespace js::gc::TuningDefaults
 
 /*
  * We start to incremental collection for a zone when a proportion of its
  * threshold is reached. This is configured by the
  * JSGC_ALLOCATION_THRESHOLD_FACTOR and
  * JSGC_ALLOCATION_THRESHOLD_FACTOR_AVOID_INTERRUPT parameters.
  */
-static const double MinAllocationThresholdFactor = 0.9;
+static const float MinAllocationThresholdFactor = 0.9f;
 
 /*
  * We may start to collect a zone before its trigger threshold is reached if
  * GCRuntime::maybeGC() is called for that zone or we start collecting other
  * zones. These eager threshold factors are not configurable.
  */
-static const double HighFrequencyEagerAllocTriggerFactor = 0.85;
-static const double LowFrequencyEagerAllocTriggerFactor = 0.9;
+static const float HighFrequencyEagerAllocTriggerFactor = 0.85f;
+static const float LowFrequencyEagerAllocTriggerFactor = 0.9f;
 
 /*
  * Don't allow heap growth factors to be set so low that collections could
  * reduce the trigger threshold.
  */
-static const double MinHighFrequencyHeapGrowthFactor =
-    1.0 / Min(HighFrequencyEagerAllocTriggerFactor, MinAllocationThresholdFactor);
-static const double MinLowFrequencyHeapGrowthFactor =
-    1.0 / Min(LowFrequencyEagerAllocTriggerFactor, MinAllocationThresholdFactor);
+static const float MinHighFrequencyHeapGrowthFactor =
+    1.0f / Min(HighFrequencyEagerAllocTriggerFactor, MinAllocationThresholdFactor);
+static const float MinLowFrequencyHeapGrowthFactor =
+    1.0f / Min(LowFrequencyEagerAllocTriggerFactor, MinAllocationThresholdFactor);
 
 /* Increase the IGC marking slice time if we are in highFrequencyGC mode. */
 static const int IGC_MARK_SLICE_MULTIPLIER = 2;
 
 const AllocKind gc::slotsToThingKind[] = {
     /*  0 */ AllocKind::OBJECT0,  AllocKind::OBJECT2,  AllocKind::OBJECT2,  AllocKind::OBJECT4,
     /*  4 */ AllocKind::OBJECT4,  AllocKind::OBJECT8,  AllocKind::OBJECT8,  AllocKind::OBJECT8,
     /*  8 */ AllocKind::OBJECT8,  AllocKind::OBJECT12, AllocKind::OBJECT12, AllocKind::OBJECT12,
@@ -1338,17 +1338,17 @@ js::gc::DumpArenaInfo()
 }
 
 #endif // JS_GC_ZEAL
 
 /*
  * Lifetime in number of major GCs for type sets attached to scripts containing
  * observed types.
  */
-static const uint64_t JIT_SCRIPT_RELEASE_TYPES_PERIOD = 20;
+static const unsigned JIT_SCRIPT_RELEASE_TYPES_PERIOD = 20;
 
 bool
 GCRuntime::init(uint32_t maxbytes, uint32_t maxNurseryBytes)
 {
     MOZ_ASSERT(SystemPageSize());
 
     {
         AutoLockGCBgAlloc lock(rt);
@@ -1482,88 +1482,88 @@ GCRuntime::setParameter(JSGCParamKey key
 
     return true;
 }
 
 bool
 GCSchedulingTunables::setParameter(JSGCParamKey key, uint32_t value, const AutoLockGC& lock)
 {
     // Limit heap growth factor to one hundred times size of current heap.
-    const double MaxHeapGrowthFactor = 100;
+    const float MaxHeapGrowthFactor = 100;
 
     switch(key) {
       case JSGC_MAX_BYTES:
         gcMaxBytes_ = value;
         break;
       case JSGC_MAX_NURSERY_BYTES:
         gcMaxNurseryBytes_ = value;
         break;
       case JSGC_HIGH_FREQUENCY_TIME_LIMIT:
         highFrequencyThreshold_ = TimeDuration::FromMilliseconds(value);
         break;
       case JSGC_HIGH_FREQUENCY_LOW_LIMIT: {
-        uint64_t newLimit = (uint64_t)value * 1024 * 1024;
-        if (newLimit == UINT64_MAX) {
+        CheckedInt<size_t> newLimit = CheckedInt<size_t>(value) * 1024 * 1024;
+        if (!newLimit.isValid()) {
             return false;
         }
-        setHighFrequencyLowLimit(newLimit);
+        setHighFrequencyLowLimit(newLimit.value());
         break;
       }
       case JSGC_HIGH_FREQUENCY_HIGH_LIMIT: {
-        uint64_t newLimit = (uint64_t)value * 1024 * 1024;
+        size_t newLimit = (size_t)value * 1024 * 1024;
         if (newLimit == 0) {
             return false;
         }
         setHighFrequencyHighLimit(newLimit);
         break;
       }
       case JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX: {
-        double newGrowth = value / 100.0;
+        float newGrowth = value / 100.0f;
         if (newGrowth < MinHighFrequencyHeapGrowthFactor || newGrowth > MaxHeapGrowthFactor) {
             return false;
         }
         setHighFrequencyHeapGrowthMax(newGrowth);
         break;
       }
       case JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN: {
-        double newGrowth = value / 100.0;
+        float newGrowth = value / 100.0f;
         if (newGrowth < MinHighFrequencyHeapGrowthFactor || newGrowth > MaxHeapGrowthFactor) {
             return false;
         }
         setHighFrequencyHeapGrowthMin(newGrowth);
         break;
       }
       case JSGC_LOW_FREQUENCY_HEAP_GROWTH: {
-        double newGrowth = value / 100.0;
+        float newGrowth = value / 100.0f;
         if (newGrowth < MinLowFrequencyHeapGrowthFactor || newGrowth > MaxHeapGrowthFactor) {
             return false;
         }
         setLowFrequencyHeapGrowth(newGrowth);
         break;
       }
       case JSGC_DYNAMIC_HEAP_GROWTH:
         dynamicHeapGrowthEnabled_ = value != 0;
         break;
       case JSGC_DYNAMIC_MARK_SLICE:
         dynamicMarkSliceEnabled_ = value != 0;
         break;
       case JSGC_ALLOCATION_THRESHOLD:
         gcZoneAllocThresholdBase_ = value * 1024 * 1024;
         break;
       case JSGC_ALLOCATION_THRESHOLD_FACTOR: {
-        double newFactor = value / 100.0;
-        if (newFactor < MinAllocationThresholdFactor || newFactor > 1.0) {
+        float newFactor = value / 100.0f;
+        if (newFactor < MinAllocationThresholdFactor || newFactor > 1.0f) {
             return false;
         }
         allocThresholdFactor_ = newFactor;
         break;
       }
       case JSGC_ALLOCATION_THRESHOLD_FACTOR_AVOID_INTERRUPT: {
-        double newFactor = value / 100.0;
-        if (newFactor < MinAllocationThresholdFactor || newFactor > 1.0) {
+        float newFactor = value / 100.0f;
+        if (newFactor < MinAllocationThresholdFactor || newFactor > 1.0f) {
             return false;
         }
         allocThresholdFactorAvoidInterrupt_ = newFactor;
         break;
       }
       case JSGC_MIN_EMPTY_CHUNK_COUNT:
         setMinEmptyChunkCount(value);
         break;
@@ -1585,59 +1585,59 @@ GCSchedulingTunables::setParameter(JSGCP
 
 void
 GCSchedulingTunables::setMaxMallocBytes(size_t value)
 {
     maxMallocBytes_ = std::min(value, TuningDefaults::MallocThresholdLimit);
 }
 
 void
-GCSchedulingTunables::setHighFrequencyLowLimit(uint64_t newLimit)
+GCSchedulingTunables::setHighFrequencyLowLimit(size_t newLimit)
 {
     highFrequencyLowLimitBytes_ = newLimit;
     if (highFrequencyLowLimitBytes_ >= highFrequencyHighLimitBytes_) {
         highFrequencyHighLimitBytes_ = highFrequencyLowLimitBytes_ + 1;
     }
     MOZ_ASSERT(highFrequencyHighLimitBytes_ > highFrequencyLowLimitBytes_);
 }
 
 void
-GCSchedulingTunables::setHighFrequencyHighLimit(uint64_t newLimit)
+GCSchedulingTunables::setHighFrequencyHighLimit(size_t newLimit)
 {
     highFrequencyHighLimitBytes_ = newLimit;
     if (highFrequencyHighLimitBytes_ <= highFrequencyLowLimitBytes_) {
         highFrequencyLowLimitBytes_ = highFrequencyHighLimitBytes_ - 1;
     }
     MOZ_ASSERT(highFrequencyHighLimitBytes_ > highFrequencyLowLimitBytes_);
 }
 
 void
-GCSchedulingTunables::setHighFrequencyHeapGrowthMin(double value)
+GCSchedulingTunables::setHighFrequencyHeapGrowthMin(float value)
 {
     highFrequencyHeapGrowthMin_ = value;
     if (highFrequencyHeapGrowthMin_ > highFrequencyHeapGrowthMax_) {
         highFrequencyHeapGrowthMax_ = highFrequencyHeapGrowthMin_;
     }
     MOZ_ASSERT(highFrequencyHeapGrowthMin_ >= MinHighFrequencyHeapGrowthFactor);
     MOZ_ASSERT(highFrequencyHeapGrowthMin_ <= highFrequencyHeapGrowthMax_);
 }
 
 void
-GCSchedulingTunables::setHighFrequencyHeapGrowthMax(double value)
+GCSchedulingTunables::setHighFrequencyHeapGrowthMax(float value)
 {
     highFrequencyHeapGrowthMax_ = value;
     if (highFrequencyHeapGrowthMax_ < highFrequencyHeapGrowthMin_) {
         highFrequencyHeapGrowthMin_ = highFrequencyHeapGrowthMax_;
     }
     MOZ_ASSERT(highFrequencyHeapGrowthMin_ >= MinHighFrequencyHeapGrowthFactor);
     MOZ_ASSERT(highFrequencyHeapGrowthMin_ <= highFrequencyHeapGrowthMax_);
 }
 
 void
-GCSchedulingTunables::setLowFrequencyHeapGrowth(double value)
+GCSchedulingTunables::setLowFrequencyHeapGrowth(float value)
 {
     lowFrequencyHeapGrowth_ = value;
     MOZ_ASSERT(lowFrequencyHeapGrowth_ >= MinLowFrequencyHeapGrowthFactor);
 }
 
 void
 GCSchedulingTunables::setMinEmptyChunkCount(uint32_t value)
 {
@@ -2047,31 +2047,31 @@ GCRuntime::setMaxMallocBytes(size_t valu
 {
     tunables.setMaxMallocBytes(value);
     mallocCounter.setMax(value, lock);
     for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
         zone->setGCMaxMallocBytes(value, lock);
     }
 }
 
-double
+float
 ZoneHeapThreshold::eagerAllocTrigger(bool highFrequencyGC) const
 {
-    double eagerTriggerFactor = highFrequencyGC ? HighFrequencyEagerAllocTriggerFactor
-                                                : LowFrequencyEagerAllocTriggerFactor;
+    float eagerTriggerFactor = highFrequencyGC ? HighFrequencyEagerAllocTriggerFactor
+                                               : LowFrequencyEagerAllocTriggerFactor;
     return eagerTriggerFactor * gcTriggerBytes();
 }
 
-/* static */ double
+/* static */ float
 ZoneHeapThreshold::computeZoneHeapGrowthFactorForHeapSize(size_t lastBytes,
                                                           const GCSchedulingTunables& tunables,
                                                           const GCSchedulingState& state)
 {
     if (!tunables.isDynamicHeapGrowthEnabled()) {
-        return 3.0;
+        return 3.0f;
     }
 
     // For small zones, our collection heuristics do not matter much: favor
     // something simple in this case.
     if (lastBytes < 1 * 1024 * 1024) {
         return tunables.lowFrequencyHeapGrowth();
     }
 
@@ -2084,51 +2084,51 @@ ZoneHeapThreshold::computeZoneHeapGrowth
     // The heap growth factor depends on the heap size after a GC and the GC
     // frequency. For low frequency GCs (more than 1sec between GCs) we let
     // the heap grow to 150%. For high frequency GCs we let the heap grow
     // depending on the heap size:
     //   lastBytes < highFrequencyLowLimit: 300%
     //   lastBytes > highFrequencyHighLimit: 150%
     //   otherwise: linear interpolation between 300% and 150% based on lastBytes
 
-    double minRatio = tunables.highFrequencyHeapGrowthMin();
-    double maxRatio = tunables.highFrequencyHeapGrowthMax();
-    double lowLimit = tunables.highFrequencyLowLimitBytes();
-    double highLimit = tunables.highFrequencyHighLimitBytes();
+    float minRatio = tunables.highFrequencyHeapGrowthMin();
+    float maxRatio = tunables.highFrequencyHeapGrowthMax();
+    float lowLimit = tunables.highFrequencyLowLimitBytes();
+    float highLimit = tunables.highFrequencyHighLimitBytes();
 
     MOZ_ASSERT(minRatio <= maxRatio);
     MOZ_ASSERT(lowLimit < highLimit);
 
     if (lastBytes <= lowLimit) {
         return maxRatio;
     }
 
     if (lastBytes >= highLimit) {
         return minRatio;
     }
 
-    double factor = maxRatio - ((maxRatio - minRatio) * ((lastBytes - lowLimit) /
+    float factor = maxRatio - ((maxRatio - minRatio) * ((lastBytes - lowLimit) /
                                                          (highLimit - lowLimit)));
 
     MOZ_ASSERT(factor >= minRatio);
     MOZ_ASSERT(factor <= maxRatio);
     return factor;
 }
 
 /* static */ size_t
-ZoneHeapThreshold::computeZoneTriggerBytes(double growthFactor, size_t lastBytes,
+ZoneHeapThreshold::computeZoneTriggerBytes(float growthFactor, size_t lastBytes,
                                            JSGCInvocationKind gckind,
                                            const GCSchedulingTunables& tunables,
                                            const AutoLockGC& lock)
 {
     size_t base = gckind == GC_SHRINK
                 ? Max(lastBytes, tunables.minEmptyChunkCount(lock) * ChunkSize)
                 : Max(lastBytes, tunables.gcZoneAllocThresholdBase());
-    double trigger = double(base) * growthFactor;
-    return size_t(Min(double(tunables.gcMaxBytes()), trigger));
+    float trigger = float(base) * growthFactor;
+    return size_t(Min(float(tunables.gcMaxBytes()), trigger));
 }
 
 void
 ZoneHeapThreshold::updateAfterGC(size_t lastBytes, JSGCInvocationKind gckind,
                                  const GCSchedulingTunables& tunables,
                                  const GCSchedulingState& state, const AutoLockGC& lock)
 {
     gcHeapGrowthFactor_ = computeZoneHeapGrowthFactorForHeapSize(lastBytes, tunables, state);
@@ -2503,30 +2503,30 @@ ArenaList::relocateArenas(Arena* toReloc
 
     check();
 
     return relocated;
 }
 
 // Skip compacting zones unless we can free a certain proportion of their GC
 // heap memory.
-static const double MIN_ZONE_RECLAIM_PERCENT = 2.0;
+static const float MIN_ZONE_RECLAIM_PERCENT = 2.0;
 
 static bool
 ShouldRelocateZone(size_t arenaCount, size_t relocCount, JS::gcreason::Reason reason)
 {
     if (relocCount == 0) {
         return false;
     }
 
     if (IsOOMReason(reason)) {
         return true;
     }
 
-    return (relocCount * 100.0) / arenaCount >= MIN_ZONE_RECLAIM_PERCENT;
+    return (relocCount * 100.0f) / arenaCount >= MIN_ZONE_RECLAIM_PERCENT;
 }
 
 static AllocKinds
 CompactingAllocKinds()
 {
     AllocKinds result;
     for (AllocKind kind : AllAllocKinds()) {
         if (IsCompactingKind(kind)) {
@@ -3550,17 +3550,17 @@ GCRuntime::maybeAllocTriggerZoneGC(Zone*
     if (usedBytes >= thresholdBytes) {
         // The threshold has been surpassed, immediately trigger a GC, which
         // will be done non-incrementally.
         triggerZoneGC(zone, JS::gcreason::ALLOC_TRIGGER, usedBytes, thresholdBytes);
         return;
     }
 
     bool wouldInterruptCollection = isIncrementalGCInProgress() && !zone->isCollecting();
-    double zoneGCThresholdFactor =
+    float zoneGCThresholdFactor =
         wouldInterruptCollection ? tunables.allocThresholdFactorAvoidInterrupt()
                                  : tunables.allocThresholdFactor();
 
     size_t igcThresholdBytes = thresholdBytes * zoneGCThresholdFactor;
 
     if (usedBytes >= igcThresholdBytes) {
         // Reduce the delay to the start of the next incremental slice.
         if (zone->gcDelayBytes < ArenaSize) {
@@ -3636,18 +3636,18 @@ GCRuntime::maybeGC(Zone* zone)
         return;
     }
 #endif
 
     if (gcIfRequested()) {
         return;
     }
 
-    double threshold = zone->threshold.eagerAllocTrigger(schedulingState.inHighFrequencyGCMode());
-    double usedBytes = zone->usage.gcBytes();
+    float threshold = zone->threshold.eagerAllocTrigger(schedulingState.inHighFrequencyGCMode());
+    float usedBytes = zone->usage.gcBytes();
     if (usedBytes > 1024 * 1024 && usedBytes >= threshold &&
         !isIncrementalGCInProgress() && !isBackgroundSweeping())
     {
         stats().recordTrigger(usedBytes, threshold);
         PrepareZoneForGC(zone);
         startGC(GC_NORMAL, JS::gcreason::EAGER_ALLOC_TRIGGER);
     }
 }
@@ -8026,29 +8026,29 @@ GCRuntime::scanZonesBeforeGC()
 // The GC can only clean up scheduledForDestruction realms that were marked live
 // by a barrier (e.g. by RemapWrappers from a navigation event). It is also
 // common to have realms held live because they are part of a cycle in gecko,
 // e.g. involving the HTMLDocument wrapper. In this case, we need to run the
 // CycleCollector in order to remove these edges before the realm can be freed.
 void
 GCRuntime::maybeDoCycleCollection()
 {
-    const static double ExcessiveGrayRealms = 0.8;
+    const static float ExcessiveGrayRealms = 0.8f;
     const static size_t LimitGrayRealms = 200;
 
     size_t realmsTotal = 0;
     size_t realmsGray = 0;
     for (RealmsIter realm(rt); !realm.done(); realm.next()) {
         ++realmsTotal;
         GlobalObject* global = realm->unsafeUnbarrieredMaybeGlobal();
         if (global && global->isMarkedGray()) {
             ++realmsGray;
         }
     }
-    double grayFraction = double(realmsGray) / double(realmsTotal);
+    float grayFraction = float(realmsGray) / float(realmsTotal);
     if (grayFraction > ExcessiveGrayRealms || realmsGray > LimitGrayRealms) {
         callDoCycleCollectionCallback(rt->mainContextFromOwnThread());
     }
 }
 
 void
 GCRuntime::checkCanCallAPI()
 {
--- a/js/src/gc/Scheduling.h
+++ b/js/src/gc/Scheduling.h
@@ -355,24 +355,24 @@ class GCSchedulingTunables
      */
     MainThreadOrGCTaskData<size_t> gcZoneAllocThresholdBase_;
 
     /*
      * JSGC_ALLOCATION_THRESHOLD_FACTOR
      *
      * Fraction of threshold.gcBytes() which triggers an incremental GC.
      */
-    UnprotectedData<double> allocThresholdFactor_;
+    UnprotectedData<float> allocThresholdFactor_;
 
     /*
      * JSGC_ALLOCATION_THRESHOLD_FACTOR_AVOID_INTERRUPT
      *
      * The same except when doing so would interrupt an already running GC.
      */
-    UnprotectedData<double> allocThresholdFactorAvoidInterrupt_;
+    UnprotectedData<float> allocThresholdFactorAvoidInterrupt_;
 
     /*
      * Number of bytes to allocate between incremental slices in GCs triggered
      * by the zone allocation threshold.
      *
      * This value does not have a JSGCParamKey parameter yet.
      */
     UnprotectedData<size_t> zoneAllocDelayBytes_;
@@ -397,28 +397,28 @@ class GCSchedulingTunables
      * JSGC_HIGH_FREQUENCY_LOW_LIMIT
      * JSGC_HIGH_FREQUENCY_HIGH_LIMIT
      * JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX
      * JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN
      *
      * When in the |highFrequencyGC| mode, these parameterize the per-zone
      * "HeapGrowthFactor" computation.
      */
-    MainThreadData<uint64_t> highFrequencyLowLimitBytes_;
-    MainThreadData<uint64_t> highFrequencyHighLimitBytes_;
-    MainThreadData<double> highFrequencyHeapGrowthMax_;
-    MainThreadData<double> highFrequencyHeapGrowthMin_;
+    MainThreadData<size_t> highFrequencyLowLimitBytes_;
+    MainThreadData<size_t> highFrequencyHighLimitBytes_;
+    MainThreadData<float> highFrequencyHeapGrowthMax_;
+    MainThreadData<float> highFrequencyHeapGrowthMin_;
 
     /*
      * JSGC_LOW_FREQUENCY_HEAP_GROWTH
      *
      * When not in |highFrequencyGC| mode, this is the global (stored per-zone)
      * "HeapGrowthFactor".
      */
-    MainThreadData<double> lowFrequencyHeapGrowth_;
+    MainThreadData<float> lowFrequencyHeapGrowth_;
 
     /*
      * JSGC_DYNAMIC_MARK_SLICE
      *
      * Doubles the length of IGC slices when in the |highFrequencyGC| mode.
      */
     MainThreadData<bool> dynamicMarkSliceEnabled_;
 
@@ -446,39 +446,39 @@ class GCSchedulingTunables
     size_t maxMallocBytes() const { return maxMallocBytes_; }
     size_t gcMaxNurseryBytes() const { return gcMaxNurseryBytes_; }
     size_t gcZoneAllocThresholdBase() const { return gcZoneAllocThresholdBase_; }
     double allocThresholdFactor() const { return allocThresholdFactor_; }
     double allocThresholdFactorAvoidInterrupt() const { return allocThresholdFactorAvoidInterrupt_; }
     size_t zoneAllocDelayBytes() const { return zoneAllocDelayBytes_; }
     bool isDynamicHeapGrowthEnabled() const { return dynamicHeapGrowthEnabled_; }
     const mozilla::TimeDuration &highFrequencyThreshold() const { return highFrequencyThreshold_; }
-    uint64_t highFrequencyLowLimitBytes() const { return highFrequencyLowLimitBytes_; }
-    uint64_t highFrequencyHighLimitBytes() const { return highFrequencyHighLimitBytes_; }
+    size_t highFrequencyLowLimitBytes() const { return highFrequencyLowLimitBytes_; }
+    size_t highFrequencyHighLimitBytes() const { return highFrequencyHighLimitBytes_; }
     double highFrequencyHeapGrowthMax() const { return highFrequencyHeapGrowthMax_; }
     double highFrequencyHeapGrowthMin() const { return highFrequencyHeapGrowthMin_; }
     double lowFrequencyHeapGrowth() const { return lowFrequencyHeapGrowth_; }
     bool isDynamicMarkSliceEnabled() const { return dynamicMarkSliceEnabled_; }
     unsigned minEmptyChunkCount(const AutoLockGC&) const { return minEmptyChunkCount_; }
     unsigned maxEmptyChunkCount() const { return maxEmptyChunkCount_; }
     uint32_t nurseryFreeThresholdForIdleCollection() const {
         return nurseryFreeThresholdForIdleCollection_;
     }
 
     MOZ_MUST_USE bool setParameter(JSGCParamKey key, uint32_t value, const AutoLockGC& lock);
     void resetParameter(JSGCParamKey key, const AutoLockGC& lock);
 
     void setMaxMallocBytes(size_t value);
 
 private:
-    void setHighFrequencyLowLimit(uint64_t value);
-    void setHighFrequencyHighLimit(uint64_t value);
-    void setHighFrequencyHeapGrowthMin(double value);
-    void setHighFrequencyHeapGrowthMax(double value);
-    void setLowFrequencyHeapGrowth(double value);
+    void setHighFrequencyLowLimit(size_t value);
+    void setHighFrequencyHighLimit(size_t value);
+    void setHighFrequencyHeapGrowthMin(float value);
+    void setHighFrequencyHeapGrowthMax(float value);
+    void setLowFrequencyHeapGrowth(float value);
     void setMinEmptyChunkCount(uint32_t value);
     void setMaxEmptyChunkCount(uint32_t value);
 };
 
 class GCSchedulingState
 {
     /*
      * Influences how we schedule and run GC's in several subtle ways. The most
@@ -556,42 +556,42 @@ class MemoryCounter
     void updateOnGCStart();
     void updateOnGCEnd(const GCSchedulingTunables& tunables, const AutoLockGC& lock);
 };
 
 // This class encapsulates the data that determines when we need to do a zone GC.
 class ZoneHeapThreshold
 {
     // The "growth factor" for computing our next thresholds after a GC.
-    GCLockData<double> gcHeapGrowthFactor_;
+    GCLockData<float> gcHeapGrowthFactor_;
 
     // GC trigger threshold for allocations on the GC heap.
     mozilla::Atomic<size_t, mozilla::Relaxed,
                     mozilla::recordreplay::Behavior::DontPreserve> gcTriggerBytes_;
 
   public:
     ZoneHeapThreshold()
-      : gcHeapGrowthFactor_(3.0),
+      : gcHeapGrowthFactor_(3.0f),
         gcTriggerBytes_(0)
     {}
 
-    double gcHeapGrowthFactor() const { return gcHeapGrowthFactor_; }
+    float gcHeapGrowthFactor() const { return gcHeapGrowthFactor_; }
     size_t gcTriggerBytes() const { return gcTriggerBytes_; }
-    double eagerAllocTrigger(bool highFrequencyGC) const;
+    float eagerAllocTrigger(bool highFrequencyGC) const;
 
     void updateAfterGC(size_t lastBytes, JSGCInvocationKind gckind,
                        const GCSchedulingTunables& tunables, const GCSchedulingState& state,
                        const AutoLockGC& lock);
     void updateForRemovedArena(const GCSchedulingTunables& tunables);
 
   private:
-    static double computeZoneHeapGrowthFactorForHeapSize(size_t lastBytes,
-                                                         const GCSchedulingTunables& tunables,
-                                                         const GCSchedulingState& state);
-    static size_t computeZoneTriggerBytes(double growthFactor, size_t lastBytes,
+    static float computeZoneHeapGrowthFactorForHeapSize(size_t lastBytes,
+                                                        const GCSchedulingTunables& tunables,
+                                                        const GCSchedulingState& state);
+    static size_t computeZoneTriggerBytes(float growthFactor, size_t lastBytes,
                                           JSGCInvocationKind gckind,
                                           const GCSchedulingTunables& tunables,
                                           const AutoLockGC& lock);
 };
 
 } // namespace gc
 } // namespace js
 
--- a/js/src/jit-test/tests/gc/gcparam.js
+++ b/js/src/jit-test/tests/gc/gcparam.js
@@ -2,26 +2,35 @@ gczeal(0);
 
 function testGetParam(key) {
     gcparam(key);
 }
 
 function testChangeParam(key) {
     let prev = gcparam(key);
     let value = prev - 1;
-    gcparam(key, value);
-    assertEq(gcparam(key), value);
-    gcparam(key, prev);
+    try {
+        gcparam(key, value);
+        assertEq(gcparam(key), value);
+        gcparam(key, prev);
+        assertEq(gcparam(key), prev);
+    } catch {
+        assertEq(gcparam(key), prev);
+    }
 }
 
-function testLargeParamValue(key) {
+function testMBParamValue(key) {
     let prev = gcparam(key);
-    const value = 1000000;
-    gcparam(key, value);
-    assertEq(gcparam(key), value);
+    const value = 1024;
+    try {
+        gcparam(key, value);
+        assertEq(gcparam(key), value);
+    } catch {
+        assertEq(gcparam(key), prev);
+    }
     gcparam(key, prev);
 }
 
 testGetParam("gcBytes");
 testGetParam("gcNumber");
 testGetParam("unusedChunks");
 testGetParam("totalChunks");
 
@@ -38,10 +47,10 @@ testChangeParam("highFrequencyHeapGrowth
 testChangeParam("lowFrequencyHeapGrowth");
 testChangeParam("dynamicHeapGrowth");
 testChangeParam("dynamicMarkSlice");
 testChangeParam("allocationThreshold");
 testChangeParam("minEmptyChunkCount");
 testChangeParam("maxEmptyChunkCount");
 testChangeParam("compactingEnabled");
 
-testLargeParamValue("highFrequencyLowLimit");
-testLargeParamValue("highFrequencyHighLimit");
+testMBParamValue("highFrequencyLowLimit");
+testMBParamValue("highFrequencyHighLimit");
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -3524,17 +3524,17 @@ class OptimizedEncodingListener
     virtual MozExternalRefCountType MOZ_XPCOM_ABI AddRef() = 0;
     virtual MozExternalRefCountType MOZ_XPCOM_ABI Release() = 0;
 
     // SpiderMonkey may optionally call storeOptimizedEncoding() after it has
     // finished processing a streamed resource.
     virtual void storeOptimizedEncoding(const uint8_t* bytes, size_t length) = 0;
 };
 
-extern JS_PUBLIC_API(bool)
+extern MOZ_MUST_USE JS_PUBLIC_API(bool)
 GetOptimizedEncodingBuildId(BuildIdCharVector* buildId);
 
 class JS_PUBLIC_API(StreamConsumer)
 {
   protected:
     // AsyncStreamConsumers are created and destroyed by SpiderMonkey.
     StreamConsumer() = default;
     virtual ~StreamConsumer() = default;
--- a/js/src/wasm/WasmModule.cpp
+++ b/js/src/wasm/WasmModule.cpp
@@ -188,17 +188,22 @@ Module::testingBlockOnTier2Complete() co
         std::this_thread::sleep_for(std::chrono::milliseconds(1));
     }
 }
 
 /* virtual */ size_t
 Module::serializedSize(const LinkData& linkData) const
 {
     JS::BuildIdCharVector buildId;
-    JS::GetOptimizedEncodingBuildId(&buildId);
+    {
+        AutoEnterOOMUnsafeRegion oom;
+        if (!GetOptimizedEncodingBuildId(&buildId)) {
+            oom.crash("getting build id");
+        }
+    }
 
     return SerializedPodVectorSize(buildId) +
            linkData.serializedSize() +
            SerializedVectorSize(imports_) +
            SerializedVectorSize(exports_) +
            SerializedVectorSize(dataSegments_) +
            SerializedVectorSize(elemSegments_) +
            SerializedVectorSize(customSections_) +
@@ -207,17 +212,22 @@ Module::serializedSize(const LinkData& l
 
 /* virtual */ void
 Module::serialize(const LinkData& linkData, uint8_t* begin, size_t size) const
 {
     MOZ_RELEASE_ASSERT(!metadata().debugEnabled);
     MOZ_RELEASE_ASSERT(code_->hasTier(Tier::Serialized));
 
     JS::BuildIdCharVector buildId;
-    JS::GetOptimizedEncodingBuildId(&buildId);
+    {
+        AutoEnterOOMUnsafeRegion oom;
+        if (!GetOptimizedEncodingBuildId(&buildId)) {
+            oom.crash("getting build id");
+        }
+    }
 
     uint8_t* cursor = begin;
     cursor = SerializePodVector(cursor, buildId);
     cursor = linkData.serialize(cursor);
     cursor = SerializeVector(cursor, imports_);
     cursor = SerializeVector(cursor, exports_);
     cursor = SerializeVector(cursor, dataSegments_);
     cursor = SerializeVector(cursor, elemSegments_);
@@ -235,17 +245,19 @@ Module::deserialize(const uint8_t* begin
         if (!metadata) {
             return nullptr;
         }
     }
 
     const uint8_t* cursor = begin;
 
     JS::BuildIdCharVector currentBuildId;
-    JS::GetOptimizedEncodingBuildId(&currentBuildId);
+    if (!GetOptimizedEncodingBuildId(&currentBuildId)) {
+        return nullptr;
+    }
 
     JS::BuildIdCharVector deserializedBuildId;
     cursor = DeserializePodVector(cursor, &deserializedBuildId);
     if (!cursor) {
         return nullptr;
     }
 
     MOZ_RELEASE_ASSERT(EqualContainers(currentBuildId, deserializedBuildId));
--- a/js/src/wasm/WasmModule.h
+++ b/js/src/wasm/WasmModule.h
@@ -190,17 +190,17 @@ class Module : public JS::WasmModule
     bool extractCode(JSContext* cx, Tier tier, MutableHandleValue vp) const;
 };
 
 typedef RefPtr<Module> MutableModule;
 typedef RefPtr<const Module> SharedModule;
 
 // JS API implementations:
 
-bool
+MOZ_MUST_USE bool
 GetOptimizedEncodingBuildId(JS::BuildIdCharVector* buildId);
 
 RefPtr<JS::WasmModule>
 DeserializeModule(PRFileDesc* bytecode, UniqueChars filename, unsigned line);
 
 } // namespace wasm
 } // namespace js
 
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -3279,17 +3279,21 @@ pref("dom.ipc.plugins.reportCrashURL", t
 pref("dom.ipc.plugins.unloadTimeoutSecs", 30);
 
 // Allow Flash async drawing mode in 64-bit release builds
 pref("dom.ipc.plugins.asyncdrawing.enabled", true);
 // Force the accelerated direct path for a subset of Flash wmode values
 pref("dom.ipc.plugins.forcedirect.enabled", true);
 
 // Enable multi by default.
+#if defined(NIGHTLY_BUILD) && !defined(MOZ_ASAN)
+pref("dom.ipc.processCount", 8);
+#else
 pref("dom.ipc.processCount", 4);
+#endif
 
 // Default to allow only one file:// URL content process.
 pref("dom.ipc.processCount.file", 1);
 
 // WebExtensions only support a single extension process.
 pref("dom.ipc.processCount.extension", 1);
 
 // Privileged content only supports a single content process.
--- a/services/sync/modules/engines/bookmarks.js
+++ b/services/sync/modules/engines/bookmarks.js
@@ -1071,16 +1071,29 @@ BookmarksStore.prototype = {
     // Figure out the local id of the parent GUID if available
     let parentGUID = record.parentid;
     if (!parentGUID) {
       throw new Error(
           `Record ${record.id} has invalid parentid: ${parentGUID}`);
     }
     this._log.debug("Remote parent is " + parentGUID);
 
+    if (record.type == "livemark") {
+      // Places no longer supports livemarks, so we replace new and updated
+      // livemarks with tombstones, and insert new change records for the engine
+      // to upload.
+      let livemarkInfo = record.toSyncBookmark();
+      let newChanges = await PlacesSyncUtils.bookmarks.removeLivemark(
+        livemarkInfo);
+      if (newChanges) {
+        this.engine._modified.insert(newChanges);
+        return;
+      }
+    }
+
     // Do the normal processing of incoming records
     await Store.prototype.applyIncoming.call(this, record);
 
     if (record.type == "folder" && record.children) {
       this._childrenToOrder[record.id] = record.children;
     }
   },
 
--- a/services/sync/tests/tps/test_bug562515.js
+++ b/services/sync/tests/tps/test_bug562515.js
@@ -34,20 +34,16 @@ var bookmarks_initial = {
   ],
   "menu/foldera": [
     { uri: "http://www.yahoo.com",
       title: "testing Yahoo",
     },
     { uri: "http://www.cnn.com",
       description: "This is a description of the site a at www.cnn.com",
     },
-    { livemark: "Livemark1",
-      feedUri: "http://rss.wunderground.com/blog/JeffMasters/rss.xml",
-      siteUri: "http://www.wunderground.com/blog/JeffMasters/show.html",
-    },
   ],
   "menu/folderb": [
     { uri: "http://www.apple.com",
       tags: [ "apple", "mac" ],
     },
   ],
   "toolbar": [
     { uri: "place:queryType=0&sort=8&maxResults=10&beginTimeRef=1&beginTime=0",
--- a/services/sync/tests/tps/test_sync.js
+++ b/services/sync/tests/tps/test_sync.js
@@ -47,23 +47,16 @@ var bookmarks_initial = {
     },
     { uri: "http://www.cnn.com",
       description: "This is a description of the site a at www.cnn.com",
       changes: {
         uri: "http://money.cnn.com",
         description: "new description",
       },
     },
-    { livemark: "Livemark1",
-      feedUri: "http://rss.wunderground.com/blog/JeffMasters/rss.xml",
-      siteUri: "http://www.wunderground.com/blog/JeffMasters/show.html",
-      changes: {
-        livemark: "LivemarkOne",
-      },
-    },
   ],
   "menu/folderb": [
     { uri: "http://www.apple.com",
       tags: ["apple", "mac"],
       changes: {
         uri: "http://www.apple.com/iphone/",
         title: "iPhone",
         location: "menu",
@@ -107,20 +100,16 @@ var bookmarks_after_first_modify = {
       },
     },
   ],
   "menu/foldera": [
     { uri: "http://money.cnn.com",
       title: "http://www.cnn.com",
       description: "new description",
     },
-    { livemark: "LivemarkOne",
-      feedUri: "http://rss.wunderground.com/blog/JeffMasters/rss.xml",
-      siteUri: "http://www.wunderground.com/blog/JeffMasters/show.html",
-    },
   ],
   "menu/folderb": [
     { uri: "http://www.yahoo.com",
       title: "testing Yahoo",
     },
   ],
   "toolbar": [
     { uri: "place:queryType=0&sort=8&maxResults=10&beginTimeRef=1&beginTime=0",
@@ -154,20 +143,16 @@ var bookmarks_after_second_modify = {
     { uri: "http://www.mozilla.com" },
     { separator: true },
   ],
   "menu/foldera": [
     { uri: "http://money.cnn.com",
       title: "http://www.cnn.com",
       description: "new description",
     },
-    { livemark: "LivemarkOne",
-      feedUri: "http://rss.wunderground.com/blog/JeffMasters/rss.xml",
-      siteUri: "http://www.wunderground.com/blog/JeffMasters/show.html",
-    },
     { folder: "Folder B",
       description: "folder description",
     },
   ],
   "menu/foldera/Folder B": [
     { uri: "http://www.yahoo.com",
       title: "testing Yahoo",
     },
--- a/services/sync/tests/unit/test_bookmark_engine.js
+++ b/services/sync/tests/unit/test_bookmark_engine.js
@@ -558,29 +558,20 @@ add_task(async function test_mismatched_
     newR.parentid = PlacesUtils.bookmarks.toolbarGuid;
 
     await store.applyIncoming(oldR);
     _("Applied old. It's a folder.");
     let oldID = await PlacesUtils.promiseItemId(oldR.id);
     _("Old ID: " + oldID);
     let oldInfo = await PlacesUtils.bookmarks.fetch(oldR.id);
     Assert.equal(oldInfo.type, PlacesUtils.bookmarks.TYPE_FOLDER);
-    Assert.ok(!PlacesUtils.annotations
-                          .itemHasAnnotation(oldID, PlacesUtils.LMANNO_FEEDURI));
 
     await store.applyIncoming(newR);
-    let newID = await PlacesUtils.promiseItemId(newR.id);
-    _("New ID: " + newID);
-
-    _("Applied new. It's a livemark.");
-    let newInfo = await PlacesUtils.bookmarks.fetch(newR.id);
-    Assert.equal(newInfo.type, PlacesUtils.bookmarks.TYPE_FOLDER);
-    Assert.ok(PlacesUtils.annotations
-                         .itemHasAnnotation(newID, PlacesUtils.LMANNO_FEEDURI));
-
+    await Assert.rejects(PlacesUtils.promiseItemId(newR.id),
+      /no item found for the given GUID/, "Should not apply Livemark");
   } finally {
     await cleanup(engine, server);
   }
 });
 
 add_task(async function test_bookmark_guidMap_fail() {
   _("Ensure that failures building the GUID map cause early death.");
 
@@ -1277,8 +1268,139 @@ add_task(async function test_mirror_sync
   equal(await buf.getSyncId(), newSyncID,
     "Should update new sync ID in mirror");
 
   strictEqual(await buf.getCollectionHighWaterMark(), 0,
     "Should reset high water mark on sync ID change in Places");
 
   await bufferedEngine.wipeClient();
 });
+
+add_bookmark_test(async function test_livemarks(engine) {
+  _("Ensure we replace new and existing livemarks with tombstones");
+
+  let server = await serverForFoo(engine);
+  await SyncTestingInfrastructure(server);
+
+  let collection = server.user("foo").collection("bookmarks");
+  let now = Date.now();
+
+  try {
+    _("Insert existing livemark");
+    let modifiedForA = now - 5 * 60 * 1000;
+    await PlacesUtils.bookmarks.insert({
+      guid: "livemarkAAAA",
+      type: PlacesUtils.bookmarks.TYPE_FOLDER,
+      parentGuid: PlacesUtils.bookmarks.menuGuid,
+      title: "A",
+      lastModified: new Date(modifiedForA),
+      dateAdded: new Date(modifiedForA),
+      source: PlacesUtils.bookmarks.SOURCE_SYNC,
+    });
+    collection.insert("menu", encryptPayload({
+      id: "menu",
+      type: "folder",
+      parentName: "",
+      title: "menu",
+      children: ["livemarkAAAA"],
+      parentid: "places",
+    }), modifiedForA / 1000);
+    collection.insert("livemarkAAAA", encryptPayload({
+      id: "livemarkAAAA",
+      type: "livemark",
+      feedUri: "http://example.com/a",
+      parentName: "menu",
+      title: "A",
+      parentid: "menu",
+    }), modifiedForA / 1000);
+
+    _("Insert remotely updated livemark");
+    await PlacesUtils.bookmarks.insert({
+      guid: "livemarkBBBB",
+      type: PlacesUtils.bookmarks.TYPE_FOLDER,
+      parentGuid: PlacesUtils.bookmarks.toolbarGuid,
+      title: "B",
+      lastModified: new Date(now),
+      dateAdded: new Date(now),
+    });
+    collection.insert("toolbar", encryptPayload({
+      id: "toolbar",
+      type: "folder",
+      parentName: "",
+      title: "toolbar",
+      children: ["livemarkBBBB"],
+      parentid: "places",
+    }), now / 1000);
+    collection.insert("livemarkBBBB", encryptPayload({
+      id: "livemarkBBBB",
+      type: "livemark",
+      feedUri: "http://example.com/b",
+      parentName: "toolbar",
+      title: "B",
+      parentid: "toolbar",
+    }), now / 1000);
+
+    _("Insert new remote livemark");
+    collection.insert("unfiled", encryptPayload({
+      id: "unfiled",
+      type: "folder",
+      parentName: "",
+      title: "unfiled",
+      children: ["livemarkCCCC"],
+      parentid: "places",
+    }), now / 1000);
+    collection.insert("livemarkCCCC", encryptPayload({
+      id: "livemarkCCCC",
+      type: "livemark",
+      feedUri: "http://example.com/c",
+      parentName: "unfiled",
+      title: "C",
+      parentid: "unfiled",
+    }), now / 1000);
+
+    _("Bump last sync time to ignore A");
+    await engine.setLastSync(Date.now() / 1000 - 60);
+
+    _("Sync");
+    await sync_engine_and_validate_telem(engine, false);
+
+    deepEqual(collection.keys().sort(), ["livemarkAAAA", "livemarkBBBB",
+      "livemarkCCCC", "menu", "mobile", "toolbar", "unfiled"],
+      "Should store original livemark A and tombstones for B and C on server");
+
+    let payloads = collection.payloads();
+
+    deepEqual(payloads.find(payload => payload.id == "menu").children,
+      ["livemarkAAAA"], "Should keep A in menu");
+    ok(!payloads.find(payload => payload.id == "livemarkAAAA").deleted,
+      "Should not upload tombstone for A");
+
+    deepEqual(payloads.find(payload => payload.id == "toolbar").children,
+      [], "Should remove B from toolbar");
+    ok(payloads.find(payload => payload.id == "livemarkBBBB").deleted,
+      "Should upload tombstone for B");
+
+    deepEqual(payloads.find(payload => payload.id == "unfiled").children,
+      [], "Should remove C from unfiled");
+    ok(payloads.find(payload => payload.id == "livemarkCCCC").deleted,
+      "Should replace C with tombstone");
+
+    await assertBookmarksTreeMatches("", [{
+      guid: PlacesUtils.bookmarks.menuGuid,
+      index: 0,
+      children: [{
+        guid: "livemarkAAAA",
+        index: 0,
+      }],
+    }, {
+      guid: PlacesUtils.bookmarks.toolbarGuid,
+      index: 1,
+    }, {
+      guid: PlacesUtils.bookmarks.unfiledGuid,
+      index: 3,
+    }, {
+      guid: PlacesUtils.bookmarks.mobileGuid,
+      index: 4,
+    }], "Should keep A and remove B locally");
+  } finally {
+    await cleanup(engine, server);
+  }
+});
deleted file mode 100644
--- a/services/sync/tests/unit/test_bookmark_livemarks.js
+++ /dev/null
@@ -1,93 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-ChromeUtils.import("resource://gre/modules/Log.jsm");
-ChromeUtils.import("resource://services-sync/record.js");
-ChromeUtils.import("resource://services-sync/engines.js");
-ChromeUtils.import("resource://services-sync/engines/bookmarks.js");
-ChromeUtils.import("resource://services-sync/util.js");
-ChromeUtils.import("resource://services-sync/service.js");
-
-// Record borrowed from Bug 631361.
-const record631361 = {
-  id: "M5bwUKK8hPyF",
-  index: 150,
-  modified: 1296768176.49,
-  payload:
-  {"id": "M5bwUKK8hPyF",
-   "type": "livemark",
-   "siteUri": "http://www.bbc.co.uk/go/rss/int/news/-/news/",
-   "feedUri": "http://fxfeeds.mozilla.com/en-US/firefox/headlines.xml",
-   "parentName": "Bookmarks Toolbar",
-   "parentid": "toolbar",
-   "title": "Latest Headlines",
-   "description": "",
-   "children":
-     ["7oBdEZB-8BMO", "SUd1wktMNCTB", "eZe4QWzo1BcY", "YNBhGwhVnQsN",
-      "92Aw2SMEkFg0", "uw0uKqrVFwd-", "x7mx2P3--8FJ", "d-jVF8UuC9Ye",
-      "DV1XVtKLEiZ5", "g4mTaTjr837Z", "1Zi5W3lwBw8T", "FEYqlUHtbBWS",
-      "qQd2u7LjosCB", "VUs2djqYfbvn", "KuhYnHocu7eg", "u2gcg9ILRg-3",
-      "hfK_RP-EC7Ol", "Aq5qsa4E5msH", "6pZIbxuJTn-K", "k_fp0iN3yYMR",
-      "59YD3iNOYO8O", "01afpSdAk2iz", "Cq-kjXDEPIoP", "HtNTjt9UwWWg",
-      "IOU8QRSrTR--", "HJ5lSlBx6d1D", "j2dz5R5U6Khc", "5GvEjrNR0yJl",
-      "67ozIBF5pNVP", "r5YB0cUx6C_w", "FtmFDBNxDQ6J", "BTACeZq9eEtw",
-      "ll4ozQ-_VNJe", "HpImsA4_XuW7", "nJvCUQPLSXwA", "94LG-lh6TUYe",
-      "WHn_QoOL94Os", "l-RvjgsZYlej", "LipQ8abcRstN", "74TiLvarE3n_",
-      "8fCiLQpQGK1P", "Z6h4WkbwfQFa", "GgAzhqakoS6g", "qyt92T8vpMsK",
-      "RyOgVCe2EAOE", "bgSEhW3w6kk5", "hWODjHKGD7Ph", "Cky673aqOHbT",
-      "gZCYT7nx3Nwu", "iJzaJxxrM58L", "rUHCRv68aY5L", "6Jc1hNJiVrV9",
-      "lmNgoayZ-ym8", "R1lyXsDzlfOd", "pinrXwDnRk6g", "Sn7TmZV01vMM",
-      "qoXyU6tcS1dd", "TRLanED-QfBK", "xHbhMeX_FYEA", "aPqacdRlAtaW",
-      "E3H04Wn2RfSi", "eaSIMI6kSrcz", "rtkRxFoG5Vqi", "dectkUglV0Dz",
-      "B4vUE0BE15No", "qgQFW5AQrgB0", "SxAXvwOhu8Zi", "0S6cRPOg-5Z2",
-      "zcZZBGeLnaWW", "B0at8hkQqVZQ", "sgPtgGulbP66", "lwtwGHSCPYaQ",
-      "mNTdpgoRZMbW", "-L8Vci6CbkJY", "bVzudKSQERc1", "Gxl9lb4DXsmL",
-      "3Qr13GucOtEh"]},
-  collection: "bookmarks",
-};
-
-function makeLivemark(p, mintGUID) {
-  let b = new Livemark("bookmarks", p.id);
-  // Copy here, because tests mutate the contents.
-  b.cleartext = Cu.cloneInto(p, {});
-
-  if (mintGUID) {
-    b.id = Utils.makeGUID();
-  }
-
-  return b;
-}
-
-add_task(async function test_livemark_invalid() {
-  let engine = new BookmarksEngine(Service);
-  await engine.initialize();
-  let store = engine._store;
-
-  _("Livemarks considered invalid by nsLivemarkService are skipped.");
-
-  _("Parent is unknown. Will be set to unfiled.");
-  let lateParentRec = makeLivemark(record631361.payload, true);
-  lateParentRec.parentid = Utils.makeGUID();
-
-  await store.create(lateParentRec);
-  let recInfo = await PlacesUtils.bookmarks.fetch(lateParentRec.id);
-  Assert.equal(recInfo.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
-
-  _("No feed URI, which is invalid. Will be skipped.");
-  let noFeedURIRec = makeLivemark(record631361.payload, true);
-  delete noFeedURIRec.cleartext.feedUri;
-  await store.create(noFeedURIRec);
-  // No exception, but no creation occurs.
-  let noFeedURIItem = await PlacesUtils.bookmarks.fetch(noFeedURIRec.id);
-  Assert.equal(null, noFeedURIItem);
-
-  _("Parent is a Livemark. Will be skipped.");
-  let lmParentRec = makeLivemark(record631361.payload, true);
-  lmParentRec.parentid = recInfo.guid;
-  await store.create(lmParentRec);
-  // No exception, but no creation occurs.
-  let lmParentItem = await PlacesUtils.bookmarks.fetch(lmParentRec.id);
-  Assert.equal(null, lmParentItem);
-
-  await engine.finalize();
-});
--- a/services/sync/tests/unit/test_bookmark_tracker.js
+++ b/services/sync/tests/unit/test_bookmark_tracker.js
@@ -853,74 +853,16 @@ add_task(async function test_onFaviconCh
     await verifyTrackedItems([]);
     Assert.equal(tracker.score, 0);
   } finally {
     _("Clean up.");
     await cleanup();
   }
 });
 
-add_task(async function test_onLivemarkAdded() {
-  _("New livemarks should be tracked");
-
-  try {
-    await startTracking();
-
-    _("Insert a livemark");
-    let totalSyncChanges = PlacesUtils.bookmarks.totalSyncChanges;
-    let livemark = await PlacesUtils.livemarks.addLivemark({
-      parentGuid: PlacesUtils.bookmarks.menuGuid,
-      // Use a local address just in case, to avoid potential aborts for
-      // non-local connections.
-      feedURI: CommonUtils.makeURI("http://localhost:0"),
-    });
-    // Prevent the livemark refresh timer from requesting the URI.
-    livemark.terminate();
-
-    await verifyTrackedItems(["menu", livemark.guid]);
-    // Two observer notifications: one for creating the livemark folder, and
-    // one for setting the "livemark/feedURI" anno on the folder.
-    Assert.equal(tracker.score, SCORE_INCREMENT_XLARGE * 2);
-    Assert.equal(PlacesUtils.bookmarks.totalSyncChanges, totalSyncChanges + 2);
-  } finally {
-    _("Clean up.");
-    await cleanup();
-  }
-});
-
-add_task(async function test_onLivemarkDeleted() {
-  _("Deleted livemarks should be tracked");
-
-  try {
-    await tracker.stop();
-
-    _("Insert a livemark");
-    let livemark = await PlacesUtils.livemarks.addLivemark({
-      parentGuid: PlacesUtils.bookmarks.menuGuid,
-      feedURI: CommonUtils.makeURI("http://localhost:0"),
-    });
-    livemark.terminate();
-
-    await startTracking();
-
-    _("Remove a livemark");
-    let totalSyncChanges = PlacesUtils.bookmarks.totalSyncChanges;
-    await PlacesUtils.livemarks.removeLivemark({
-      guid: livemark.guid,
-    });
-
-    await verifyTrackedItems(["menu", livemark.guid]);
-    Assert.equal(tracker.score, SCORE_INCREMENT_XLARGE);
-    Assert.equal(PlacesUtils.bookmarks.totalSyncChanges, totalSyncChanges + 2);
-  } finally {
-    _("Clean up.");
-    await cleanup();
-  }
-});
-
 add_task(async function test_async_onItemMoved_moveToFolder() {
   _("Items moved via `moveToFolder` should be tracked");
 
   try {
     await tracker.stop();
 
     await PlacesUtils.bookmarks.insertTree({
       guid: PlacesUtils.bookmarks.menuGuid,
--- a/services/sync/tests/unit/xpcshell.ini
+++ b/services/sync/tests/unit/xpcshell.ini
@@ -131,17 +131,16 @@ tags = addons
 tags = addons
 [test_addons_validator.js]
 tags = addons
 [test_bookmark_batch_fail.js]
 [test_bookmark_duping.js]
 run-sequentially = Frequent timeouts, bug 1395148
 [test_bookmark_engine.js]
 [test_bookmark_invalid.js]
-[test_bookmark_livemarks.js]
 [test_bookmark_order.js]
 [test_bookmark_places_query_rewriting.js]
 [test_bookmark_record.js]
 [test_bookmark_repair.js]
 skip-if = release_or_beta
 run-sequentially = Frequent timeouts, bug 1395148
 [test_bookmark_repair_requestor.js]
 # Repair is enabled only on Aurora and Nightly
--- a/services/sync/tps/extensions/tps/resource/modules/bookmarks.jsm
+++ b/services/sync/tps/extensions/tps/resource/modules/bookmarks.jsm
@@ -2,17 +2,17 @@
  * 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/. */
 
  /* This is a JavaScript module (JSM) to be imported via
   * Components.utils.import() and acts as a singleton. Only the following
   * listed symbols will exposed on import, and only when and where imported.
   */
 
-var EXPORTED_SYMBOLS = ["PlacesItem", "Bookmark", "Separator", "Livemark",
+var EXPORTED_SYMBOLS = ["PlacesItem", "Bookmark", "Separator",
                         "BookmarkFolder", "DumpBookmarks"];
 
 ChromeUtils.import("resource://gre/modules/PlacesBackups.jsm");
 ChromeUtils.import("resource://gre/modules/PlacesSyncUtils.jsm");
 ChromeUtils.import("resource://gre/modules/PlacesUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://tps/logger.jsm");
 
@@ -35,19 +35,16 @@ function PlacesItemProps(props) {
   this.uri = null;
   this.keyword = null;
   this.title = null;
   this.after = null;
   this.before = null;
   this.folder = null;
   this.position = null;
   this.delete = false;
-  this.siteUri = null;
-  this.feedUri = null;
-  this.livemark = null;
   this.tags = null;
   this.last_item_pos = null;
   this.type = null;
 
   for (var prop in props) {
     if (prop in this) {
       this[prop] = props[prop];
     }
@@ -85,17 +82,17 @@ PlacesItem.prototype = {
   _typeMap: new Map([
     [PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER, PlacesUtils.bookmarks.TYPE_FOLDER],
     [PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR, PlacesUtils.bookmarks.TYPE_SEPARATOR],
     [PlacesUtils.TYPE_X_MOZ_PLACE, PlacesUtils.bookmarks.TYPE_BOOKMARK],
   ]),
 
   toString() {
     var that = this;
-    var props = ["uri", "title", "location", "folder", "feedUri", "siteUri", "livemark"];
+    var props = ["uri", "title", "location", "folder"];
     var string = (this.props.type ? this.props.type + " " : "") +
       "(" +
       (function() {
         var ret = [];
         for (var i in props) {
           if (that.props[props[i]]) {
             ret.push(props[i] + ": " + that.props[props[i]]);
           }
@@ -640,144 +637,16 @@ BookmarkFolder.prototype = {
     await this.SetPosition(this.updateProps.position);
     await this.SetTitle(this.updateProps.folder);
   },
 };
 
 extend(BookmarkFolder, PlacesItem);
 
 /**
- * Livemark class constructor. Initialzes instance properties.
- */
-function Livemark(props) {
-  PlacesItem.call(this, props);
-  this.props.type = "livemark";
-}
-
-/**
- * Livemark instance methods
- */
-Livemark.prototype = {
-  /**
-   * Create
-   *
-   * Creates the livemark described by this object's properties.
-   *
-   * @return the id of the created livemark
-   */
-  async Create() {
-    this.props.parentGuid = await this.GetOrCreateFolder(this.props.location);
-    Logger.AssertTrue(this.props.parentGuid, "Unable to create " +
-      "folder, error creating parent folder " + this.props.location);
-    let siteURI = null;
-    if (this.props.siteUri != null)
-      siteURI = Services.io.newURI(this.props.siteUri);
-    let livemarkObj = {parentGuid: this.props.parentGuid,
-                       title: this.props.livemark,
-                       siteURI,
-                       feedURI: Services.io.newURI(this.props.feedUri),
-                       index: PlacesUtils.bookmarks.DEFAULT_INDEX};
-
-    let livemark = await PlacesUtils.livemarks.addLivemark(livemarkObj);
-    this.props.guid = livemark.guid;
-    return this.props.guid;
-  },
-
-  /**
-   * Find
-   *
-   * Locates the livemark which corresponds to this object's
-   * properties.
-   *
-   * @return the item guid if the livemark was found, otherwise null
-   */
-  async Find() {
-    this.props.parentGuid = await this.GetFolder(this.props.location);
-    if (this.props.parentGuid == null) {
-      Logger.logError("Unable to find folder " + this.props.location);
-      return null;
-    }
-    this.props.guid = await this.GetPlacesChildGuid(
-                              this.props.parentGuid,
-                              PlacesUtils.bookmarks.TYPE_FOLDER,
-                              this.props.livemark);
-    if (!this.props.guid) {
-      Logger.logPotentialError("can't find livemark for " + this.toString());
-      return null;
-    }
-    let itemId = await PlacesUtils.promiseItemId(this.props.guid);
-    if (!PlacesUtils.annotations
-                    .itemHasAnnotation(itemId, PlacesUtils.LMANNO_FEEDURI)) {
-      Logger.logPotentialError("livemark folder found, but it's just a regular folder, for " +
-        this.toString());
-      this.props.guid = null;
-      return null;
-    }
-    let feedURI = Services.io.newURI(this.props.feedUri);
-    let lmFeedURISpec =
-      PlacesUtils.annotations.getItemAnnotation(itemId,
-                                                PlacesUtils.LMANNO_FEEDURI);
-    if (feedURI.spec != lmFeedURISpec) {
-      Logger.logPotentialError("livemark feed uri not correct, expected: " +
-        this.props.feedUri + ", actual: " + lmFeedURISpec +
-        " for " + this.toString());
-      return null;
-    }
-    if (this.props.siteUri != null) {
-      let siteURI = Services.io.newURI(this.props.siteUri);
-      let lmSiteURISpec =
-        PlacesUtils.annotations.getItemAnnotation(itemId,
-                                                  PlacesUtils.LMANNO_SITEURI);
-      if (siteURI.spec != lmSiteURISpec) {
-        Logger.logPotentialError("livemark site uri not correct, expected: " +
-        this.props.siteUri + ", actual: " + lmSiteURISpec + " for " +
-        this.toString());
-        return null;
-      }
-    }
-    if (!(await this.CheckPosition(this.props.before,
-                                   this.props.after,
-                                   this.props.last_item_pos)))
-      return null;
-    return this.props.guid;
-  },
-
-  /**
-   * Update
-   *
-   * Updates this livemark's properties according the properties on this
-   * object's 'updateProps' property.
-   *
-   * @return nothing
-   */
-  async Update() {
-    Logger.AssertTrue(this.props.guid, "Invalid guid during Update");
-    await this.SetLocation(this.updateProps.location);
-    await this.SetPosition(this.updateProps.position);
-    await this.SetTitle(this.updateProps.livemark);
-    return true;
-  },
-
-  /**
-   * Remove
-   *
-   * Removes this livemark.  The livemark should have been located previously
-   * by a call to Find.
-   *
-   * @return nothing
-   */
-  async Remove() {
-    Logger.AssertTrue(this.props.guid, "Invalid guid during Remove");
-    await PlacesUtils.bookmarks.remove(this.props.guid);
-  },
-};
-
-extend(Livemark, PlacesItem);
-
-/**
  * Separator class constructor. Initializes instance properties.
  */
 function Separator(props) {
   PlacesItem.call(this, props);
   this.props.type = "separator";
 }
 
 /**
--- a/toolkit/components/places/BookmarkHTMLUtils.jsm
+++ b/toolkit/components/places/BookmarkHTMLUtils.jsm
@@ -16,17 +16,18 @@
  *   For backwards compatibility, if we don't find this, we assume that the
  *   hierarchy is rooted at the bookmarks menu.
  * Heading := any heading other than h1
  *   Old version used this to set attributes on the current container. We only
  *   care about the content of the heading container, which contains the title
  *   of the bookmark container.
  * Bookmark := a
  *   HREF is the destination of the bookmark
- *   FEEDURL is the URI of the RSS feed if this is a livemark.
+ *   FEEDURL is the URI of the RSS feed. This is deprecated and no more
+ *   supported, but some old files may still contain it.
  *   LAST_CHARSET is stored as an annotation so that the next time we go to
  *     that page we remember the user's preference.
  *   ICON will be stored in the favicon service
  *   ICON_URI is new for places bookmarks.html, it refers to the original
  *     URI of the favicon so we don't have to make up favicon URLs.
  *   Text of the <a> container is the name of the bookmark
  *   Ignored: LAST_VISIT, ID (writing out non-RDF IDs can confuse Firefox 2)
  * Bookmark comment := dd
@@ -276,22 +277,16 @@ function Frame(aFolder) {
    * contains the URL of the previous bookmark created. This is used so that
    * when we encounter a <dd>, we know what bookmark to associate the text with.
    * This is cleared whenever we hit a <h3>, so that we know NOT to save this
    * with a bookmark, but to keep it until
    */
   this.previousLink = null;
 
   /**
-   * contains the URL of the previous livemark, so that when the link ends,
-   * and the livemark title is known, we can create it.
-   */
-  this.previousFeed = null;
-
-  /**
    * Contains a reference to the last created bookmark or folder object.
    */
   this.previousItem = null;
 
   /**
    * Contains the date-added and last-modified-date of an imported item.
    * Used to override the values set by insertBookmark, createFolder, etc.
    */
@@ -483,85 +478,57 @@ BookmarkImporter.prototype = {
   /*
    * Handles "<a" tags by creating a new bookmark. The title of the bookmark
    * will be the text content, which will be stuffed in previousText for us
    * and which will be saved by handleLinkEnd
    */
   _handleLinkBegin: function handleLinkBegin(aElt) {
     let frame = this._curFrame;
 
-    frame.previousFeed = null;
     frame.previousItem = null;
     frame.previousText = ""; // Will hold link text, clear it.
 
     // Get the attributes we care about.
     let href = this._safeTrim(aElt.getAttribute("href"));
-    let feedUrl = this._safeTrim(aElt.getAttribute("feedurl"));
     let icon = this._safeTrim(aElt.getAttribute("icon"));
     let iconUri = this._safeTrim(aElt.getAttribute("icon_uri"));
     let lastCharset = this._safeTrim(aElt.getAttribute("last_charset"));
     let keyword = this._safeTrim(aElt.getAttribute("shortcuturl"));
     let postData = this._safeTrim(aElt.getAttribute("post_data"));
     let dateAdded = this._safeTrim(aElt.getAttribute("add_date"));
     let lastModified = this._safeTrim(aElt.getAttribute("last_modified"));
     let tags = this._safeTrim(aElt.getAttribute("tags"));
 
-    // For feeds, get the feed URL.  If it is invalid, mPreviousFeed will be
-    // NULL and we'll create it as a normal bookmark.
-    if (feedUrl) {
-      frame.previousFeed = feedUrl;
-    }
-
     // Ignore <a> tags that have no href.
-    if (href) {
-      // Save the address if it's valid.  Note that we ignore errors if this is a
-      // feed since href is optional for them.
-      try {
-        frame.previousLink = Services.io.newURI(href).spec;
-      } catch (e) {
-        if (!frame.previousFeed) {
-          frame.previousLink = null;
-          return;
-        }
-      }
-    } else {
+    try {
+      frame.previousLink = Services.io.newURI(href).spec;
+    } catch (e) {
       frame.previousLink = null;
-      // The exception is for feeds, where the href is an optional component
-      // indicating the source web site.
-      if (!frame.previousFeed) {
-        return;
-      }
+      return;
     }
 
     let bookmark = {};
 
-    // Only set the url for bookmarks, not for livemarks.
-    if (frame.previousLink && !frame.previousFeed) {
+    // Only set the url for bookmarks.
+    if (frame.previousLink) {
       bookmark.url = frame.previousLink;
     }
 
     if (dateAdded) {
       bookmark.dateAdded = this._convertImportedDateToInternalDate(dateAdded);
     }
     // Save bookmark's last modified date.
     if (lastModified) {
       bookmark.lastModified = this._convertImportedDateToInternalDate(lastModified);
     }
 
     if (!dateAdded && lastModified) {
       bookmark.dateAdded = bookmark.lastModified;
     }
 
-    if (frame.previousFeed) {
-      // This is a livemark, we've done all we need to do here, so finish early.
-      frame.folder.children.push(bookmark);
-      frame.previousItem = bookmark;
-      return;
-    }
-
     if (tags) {
       bookmark.tags = tags.split(",").filter(aTag => aTag.length > 0 &&
         aTag.length <= PlacesUtils.bookmarks.MAX_TAG_LENGTH);
 
       // If we end up with none, then delete the property completely.
       if (!bookmark.tags.length) {
         delete bookmark.tags;
       }
@@ -622,36 +589,16 @@ BookmarkImporter.prototype = {
   /**
    * Saves the title for the given bookmark.
    */
   _handleLinkEnd: function handleLinkEnd() {
     let frame = this._curFrame;
     frame.previousText = frame.previousText.trim();
 
     if (frame.previousItem != null) {
-      if (frame.previousFeed) {
-        if (!frame.previousItem.hasOwnProperty("annos")) {
-          frame.previousItem.annos = [];
-        }
-        frame.previousItem.type = PlacesUtils.bookmarks.TYPE_FOLDER;
-        frame.previousItem.annos.push({
-          "name": PlacesUtils.LMANNO_FEEDURI,
-          "flags": 0,
-          "expires": 4,
-          "value": frame.previousFeed,
-        });
-        if (frame.previousLink) {
-          frame.previousItem.annos.push({
-            "name": PlacesUtils.LMANNO_SITEURI,
-            "flags": 0,
-            "expires": 4,
-            "value": frame.previousLink,
-          });
-        }
-      }
       frame.previousItem.title = frame.previousText;
     }
 
     frame.previousText = "";
   },
 
   _openContainer: function openContainer(aElt) {
     if (aElt.namespaceURI != "http://www.w3.org/1999/xhtml") {
@@ -951,19 +898,17 @@ BookmarkExporter.prototype = {
     else
       this._writeLine(aIndent + "</DL><p>");
   },
 
   async _writeContainerContents(aItem, aIndent) {
     let localIndent = aIndent + EXPORT_INDENT;
 
     for (let child of aItem.children) {
-      if (child.annos && child.annos.some(anno => anno.name == PlacesUtils.LMANNO_FEEDURI)) {
-        this._writeLivemark(child, localIndent);
-      } else if (child.type == PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER) {
+      if (child.type == PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER) {
         await this._writeContainer(child, localIndent);
       } else if (child.type == PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR) {
         this._writeSeparator(child, localIndent);
       } else {
         await this._writeItem(child, localIndent);
       }
     }
   },
@@ -971,27 +916,16 @@ BookmarkExporter.prototype = {
   _writeSeparator(aItem, aIndent) {
     this._write(aIndent + "<HR");
     // We keep exporting separator titles, but don't support them anymore.
     if (aItem.title)
       this._writeAttribute("NAME", escapeHtmlEntities(aItem.title));
     this._write(">");
   },
 
-  _writeLivemark(aItem, aIndent) {
-    this._write(aIndent + "<DT><A");
-    let feedSpec = aItem.annos.find(anno => anno.name == PlacesUtils.LMANNO_FEEDURI).value;
-    this._writeAttribute("FEEDURL", escapeUrl(feedSpec));
-    let siteSpecAnno = aItem.annos.find(anno => anno.name == PlacesUtils.LMANNO_SITEURI);
-    if (siteSpecAnno)
-      this._writeAttribute("HREF", escapeUrl(siteSpecAnno.value));
-    this._writeLine(">" + escapeHtmlEntities(aItem.title) + "</A>");
-    this._writeDescription(aItem, aIndent);
-  },
-
   async _writeItem(aItem, aIndent) {
     try {
       NetUtil.newURI(aItem.uri);
     } catch (ex) {
       // If the item URI is invalid, skip the item instead of failing later.
       return;
     }
 
--- a/toolkit/components/places/Bookmarks.jsm
+++ b/toolkit/components/places/Bookmarks.jsm
@@ -383,17 +383,16 @@ var Bookmarks = Object.freeze({
     }
     if (options && typeof options != "object") {
       throw new Error("Options should be a valid object");
     }
     let fixupOrSkipInvalidEntries = options && !!options.fixupOrSkipInvalidEntries;
 
     // Serialize the tree into an array of items to insert into the db.
     let insertInfos = [];
-    let insertLivemarkInfos = [];
     let urlsThatMightNeedPlaces = [];
 
     // We want to use the same 'last added' time for all the entries
     // we import (so they won't differ by a few ms based on where
     // they are in the tree, and so we don't needlessly construct
     // multiple dates).
     let fallbackLastAdded = new Date();
 
@@ -472,30 +471,16 @@ var Bookmarks = Object.freeze({
           insertInfo.index = null;
         }
         // Store the URL if this is a bookmark, so we can ensure we create an
         // entry in moz_places for it.
         if (insertInfo.type == Bookmarks.TYPE_BOOKMARK) {
           urlsThatMightNeedPlaces.push(insertInfo.url);
         }
 
-        // As we don't track indexes for children of root folders, and we
-        // insert livemarks separately, we create a temporary placeholder in
-        // the bookmarks, and later we'll replace it by the real livemark.
-        if (isLivemark(insertInfo)) {
-          // Make the current insertInfo item a placeholder.
-          let livemarkInfo = Object.assign({}, insertInfo);
-
-          // Delete the annotations that make it a livemark.
-          delete insertInfo.annos;
-
-          // Now save the livemark info for later.
-          insertLivemarkInfos.push(livemarkInfo);
-        }
-
         insertInfos.push(insertInfo);
         // Process any children. We have to use info.children here rather than
         // insertInfo.children because validateBookmarkObject doesn't copy over
         // the children ref, as the default bookmark validators object doesn't
         // know about children.
         if (info.children) {
           // start children of this item off at index 0.
           let childrenLastAdded = appendInsertionInfoForInfoArray(info.children, 0, insertInfo.guid);
@@ -528,35 +513,16 @@ var Bookmarks = Object.freeze({
 
       if (treeParent._parentId == PlacesUtils.tagsFolderId) {
         throw new Error("Can't use insertTree to insert tags.");
       }
 
       await insertBookmarkTree(insertInfos, source, treeParent,
                                urlsThatMightNeedPlaces, lastAddedForParent);
 
-      for (let info of insertLivemarkInfos) {
-        try {
-          await insertLivemarkData(info);
-        } catch (ex) {
-          // This can arguably fail, if some of the livemarks data is invalid.
-          if (fixupOrSkipInvalidEntries) {
-            // The placeholder should have been removed at this point, thus we
-            // can avoid to notify about it.
-            let placeholderIndex = insertInfos.findIndex(item => item.guid == info.guid);
-            if (placeholderIndex != -1) {
-              insertInfos.splice(placeholderIndex, 1);
-            }
-          } else {
-            // Throw if we're not lenient to input mistakes.
-            throw ex;
-          }
-        }
-      }
-
       // Now update the indices of root items in the objects we return.
       // These may be wrong if someone else modified the table between
       // when we fetched the parent and inserted our items, but the actual
       // inserts will have been correct, and we don't want to query the DB
       // again if we don't have to. bug 1347230 covers improving this.
       let rootIndex = treeParent._childCount;
       for (let insertInfo of insertInfos) {
         if (insertInfo.parentGuid == tree.guid) {
@@ -1821,27 +1787,16 @@ function insertBookmark(item, parent) {
       // ...though we don't wait for the calculation.
       updateFrecency(db, [item.url]).catch(Cu.reportError);
     }
 
     return item;
   });
 }
 
-/**
- * Determines if a bookmark is a Livemark depending on how it is annotated.
- *
- * @param {Object} node The bookmark node to check.
- * @returns {Boolean} True if the node is a Livemark, false otherwise.
- */
-function isLivemark(node) {
-  return node.type == Bookmarks.TYPE_FOLDER && node.annos &&
-         node.annos.some(anno => anno.name == PlacesUtils.LMANNO_FEEDURI);
-}
-
 function insertBookmarkTree(items, source, parent, urls, lastAddedForParent) {
   return PlacesUtils.withConnectionWrapper("Bookmarks.jsm: insertBookmarkTree", async function(db) {
     await db.executeTransaction(async function transaction() {
       await maybeInsertManyPlaces(db, urls);
 
       let syncChangeDelta =
         PlacesSyncUtils.bookmarks.determineSyncChangeDelta(source);
       let syncStatus =
@@ -1882,66 +1837,16 @@ function insertBookmarkTree(items, sourc
     // We don't wait for the frecency calculation.
     updateFrecency(db, urls, true).catch(Cu.reportError);
 
     return items;
   });
 }
 
 /**
- * Handles data for a Livemark insert.
- *
- * @param {Object} item Livemark item that need to be added.
- */
-async function insertLivemarkData(item) {
-  // Delete the placeholder but note the index of it, so that we can insert the
-  // livemark item at the right place.
-  let placeholder = await Bookmarks.fetch(item.guid);
-  let index = placeholder.index;
-  await removeBookmarks([item], {source: item.source});
-
-  let feedURI = null;
-  let siteURI = null;
-  item.annos = item.annos.filter(function(aAnno) {
-    switch (aAnno.name) {
-      case PlacesUtils.LMANNO_FEEDURI:
-        feedURI = NetUtil.newURI(aAnno.value);
-        return false;
-      case PlacesUtils.LMANNO_SITEURI:
-        siteURI = NetUtil.newURI(aAnno.value);
-        return false;
-      default:
-        return true;
-    }
-  });
-
-  if (feedURI) {
-    item.feedURI = feedURI;
-    item.siteURI = siteURI;
-    item.index = index;
-
-    if (item.dateAdded) {
-      item.dateAdded = PlacesUtils.toPRTime(item.dateAdded);
-    }
-    if (item.lastModified) {
-      item.lastModified = PlacesUtils.toPRTime(item.lastModified);
-    }
-
-    let livemark = await PlacesUtils.livemarks.addLivemark(item);
-
-    let id = livemark.id;
-    if (item.annos && item.annos.length) {
-      // Note: for annotations, we intentionally skip updating the last modified
-      // value for the bookmark, to avoid a second update of the added bookmark.
-      PlacesUtils.setAnnotationsForItem(id, item.annos, item.source, true);
-    }
-  }
-}
-
-/**
  * Handles special data on a bookmark, e.g. annotations, keywords, tags, charsets,
  * inserting the data into the appropriate place.
  *
  * @param {Integer} itemId The ID of the item within the bookmarks database.
  * @param {Object} item The bookmark item with possible special data to be inserted.
  */
 async function handleBookmarkItemSpecialData(itemId, item) {
   if (item.annos && item.annos.length) {
--- a/toolkit/components/places/Database.cpp
+++ b/toolkit/components/places/Database.cpp
@@ -99,20 +99,16 @@
 #define DATABASE_BUSY_TIMEOUT_MS 100
 
 // Old Sync GUID annotation.
 #define SYNCGUID_ANNO NS_LITERAL_CSTRING("sync/guid")
 
 // Places string bundle, contains internationalized bookmark root names.
 #define PLACES_BUNDLE "chrome://places/locale/places.properties"
 
-// Livemarks annotations.
-#define LMANNO_FEEDURI "livemark/feedURI"
-#define LMANNO_SITEURI "livemark/siteURI"
-
 // This is no longer used & obsolete except for during migration.
 // Note: it may still be found in older places databases.
 #define MOBILE_ROOT_ANNO "mobile/bookmarksRoot"
 
 // This annotation is no longer used & is obsolete, but here for migration.
 #define LAST_USED_ANNO NS_LITERAL_CSTRING("bookmarkPropertiesDialog/folderLastUsed")
 // This is key in the meta table that the LAST_USED_ANNO is migrated to.
 #define LAST_USED_FOLDERS_META_KEY NS_LITERAL_CSTRING("places/bookmarks/edit/lastusedfolder")
--- a/toolkit/components/places/PlacesSyncUtils.jsm
+++ b/toolkit/components/places/PlacesSyncUtils.jsm
@@ -1166,60 +1166,52 @@ const BookmarkSyncUtils = PlacesSyncUtil
    *
    *  - kind (all): A string representing the item's kind.
    *  - recordId (all): The item's record ID.
    *  - parentRecordId (all): The record ID of the item's parent.
    *  - parentTitle (all): The title of the item's parent, used for de-duping.
    *    Omitted for the Places root and parents with empty titles.
    *  - dateAdded (all): Timestamp in milliseconds, when the bookmark was added
    *    or created on a remote device if known.
-   *  - title ("bookmark", "folder", "livemark", "query"): The item's title.
+   *  - title ("bookmark", "folder", "query"): The item's title.
    *    Omitted if empty.
    *  - url ("bookmark", "query"): The item's URL.
    *  - tags ("bookmark", "query"): An array containing the item's tags.
    *  - keyword ("bookmark"): The bookmark's keyword, if one exists.
-   *  - feed ("livemark"): A `URL` object pointing to the livemark's feed URL.
-   *  - site ("livemark"): A `URL` object pointing to the livemark's site URL,
-   *    or `null` if one isn't set.
    *  - childRecordIds ("folder"): An array containing the record IDs of the item's
    *    children, used to determine child order.
    *  - folder ("query"): The tag folder name, if this is a tag query.
    *  - index ("separator"): The separator's position within its parent.
    */
   async fetch(recordId) {
     let guid = BookmarkSyncUtils.recordIdToGuid(recordId);
     let bookmarkItem = await PlacesUtils.bookmarks.fetch(guid);
     if (!bookmarkItem) {
       return null;
     }
     return PlacesUtils.withConnectionWrapper("BookmarkSyncUtils: fetch",
       async function(db) {
         // Convert the Places bookmark object to a Sync bookmark and add
         // kind-specific properties. Titles are required for bookmarks,
-        // folders, and livemarks; optional for queries, and omitted for
-        // separators.
+        // and folders; optional for queries, and omitted for separators.
         let kind = await getKindForItem(db, bookmarkItem);
         let item;
         switch (kind) {
           case BookmarkSyncUtils.KINDS.BOOKMARK:
             item = await fetchBookmarkItem(db, bookmarkItem);
             break;
 
           case BookmarkSyncUtils.KINDS.QUERY:
             item = await fetchQueryItem(db, bookmarkItem);
             break;
 
           case BookmarkSyncUtils.KINDS.FOLDER:
             item = await fetchFolderItem(db, bookmarkItem);
             break;
 
-          case BookmarkSyncUtils.KINDS.LIVEMARK:
-            item = await fetchLivemarkItem(db, bookmarkItem);
-            break;
-
           case BookmarkSyncUtils.KINDS.SEPARATOR:
             item = await placesBookmarkToSyncBookmark(db, bookmarkItem);
             item.index = bookmarkItem.index;
             break;
 
           default:
             throw new Error(`Unknown bookmark kind: ${kind}`);
         }
@@ -1287,16 +1279,62 @@ const BookmarkSyncUtils = PlacesSyncUtil
         SET syncChangeCounter = syncChangeCounter + :syncChangeDelta
       WHERE type = :type AND
             fk = (SELECT id FROM moz_places WHERE url_hash = hash(:url) AND
                   url = :url)`,
       { syncChangeDelta, type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
         url: url.href });
   },
 
+  async removeLivemark(livemarkInfo) {
+    let info = validateSyncBookmarkObject(
+      "BookmarkSyncUtils: removeLivemark",
+      livemarkInfo,
+      { kind: { required: true,
+                validIf: b => b.kind == BookmarkSyncUtils.KINDS.LIVEMARK },
+        recordId: { required: true },
+        parentRecordId: { required: true } });
+
+    let guid = BookmarkSyncUtils.recordIdToGuid(info.recordId);
+    let parentGuid = BookmarkSyncUtils.recordIdToGuid(info.parentRecordId);
+
+    return PlacesUtils.withConnectionWrapper(
+      "BookmarkSyncUtils: removeLivemark",
+      async function(db) {
+        if (await GUIDMissing(guid)) {
+          // If the livemark doesn't exist in the database, insert a tombstone
+          // and bump its parent's change counter to ensure it's removed from
+          // the server in the current sync.
+          await db.executeTransaction(async function() {
+            await db.executeCached(`
+              UPDATE moz_bookmarks SET
+                syncChangeCounter = syncChangeCounter + 1
+              WHERE guid = :parentGuid`,
+              { parentGuid });
+
+            await db.executeCached(`
+              INSERT OR IGNORE INTO moz_bookmarks_deleted (guid, dateRemoved)
+              VALUES (:guid, ${PlacesUtils.toPRTime(Date.now())})`,
+              { guid });
+          });
+        } else {
+          await PlacesUtils.bookmarks.remove({
+            guid,
+            // `SYNC_REPARENT_REMOVED_FOLDER_CHILDREN` bumps the change counter for
+            // the child and its new parent, without incrementing the bookmark
+            // tracker's score.
+            source: PlacesUtils.bookmarks.SOURCES.SYNC_REPARENT_REMOVED_FOLDER_CHILDREN,
+          });
+        }
+
+        return pullSyncChanges(db, [guid, parentGuid]);
+      }
+    );
+  },
+
   /**
    * Returns `0` if no sensible timestamp could be found.
    * Otherwise, returns the earliest sensible timestamp between `existingMillis`
    * and `serverMillis`.
    */
   ratchetTimestampBackwards(existingMillis, serverMillis, lowerBound = BookmarkSyncUtils.EARLIEST_BOOKMARK_TIMESTAMP) {
     const possible = [+existingMillis, +serverMillis].filter(n => !isNaN(n) && n > lowerBound);
     if (!possible.length) {
@@ -1467,63 +1505,31 @@ async function insertSyncBookmark(db, in
       insertInfo.parentRecordId} doesn't exist; reparenting to unfiled`);
     insertInfo.parentRecordId = "unfiled";
   }
 
   // If we're inserting a tag query, make sure the tag exists and fix the
   // folder ID to refer to the local tag folder.
   insertInfo = await updateTagQueryFolder(db, insertInfo);
 
-  let newItem;
-  if (insertInfo.kind == BookmarkSyncUtils.KINDS.LIVEMARK) {
-    newItem = await insertSyncLivemark(db, insertInfo);
-  } else {
-    let bookmarkInfo = syncBookmarkToPlacesBookmark(insertInfo);
-    let bookmarkItem = await PlacesUtils.bookmarks.insert(bookmarkInfo);
-    newItem = await insertBookmarkMetadata(db, bookmarkItem, insertInfo);
-  }
-
-  if (!newItem) {
-    return null;
-  }
+  let bookmarkInfo = syncBookmarkToPlacesBookmark(insertInfo);
+  let bookmarkItem = await PlacesUtils.bookmarks.insert(bookmarkInfo);
+  let newItem = await insertBookmarkMetadata(db, bookmarkItem, insertInfo);
 
   // If the item is an orphan, annotate it with its real parent record ID.
   if (isOrphan) {
     await annotateOrphan(newItem, requestedParentRecordId);
   }
 
   // Reparent all orphans that expect this folder as the parent.
   await reparentOrphans(db, newItem);
 
   return newItem;
 }
 
-// Inserts a synced livemark.
-async function insertSyncLivemark(db, insertInfo) {
-  if (!insertInfo.feed) {
-    BookmarkSyncLog.debug(`insertSyncLivemark: ${
-      insertInfo.recordId} missing feed URL`);
-    return null;
-  }
-  let livemarkInfo = syncBookmarkToPlacesBookmark(insertInfo);
-  let parentIsLivemark = await getAnno(db, livemarkInfo.parentGuid,
-                                       PlacesUtils.LMANNO_FEEDURI);
-  if (parentIsLivemark) {
-    // A livemark can't be a descendant of another livemark.
-    BookmarkSyncLog.debug(`insertSyncLivemark: Invalid parent ${
-      insertInfo.parentRecordId}; skipping livemark record ${
-      insertInfo.recordId}`);
-    return null;
-  }
-
-  let livemarkItem = await PlacesUtils.livemarks.addLivemark(livemarkInfo);
-
-  return insertBookmarkMetadata(db, livemarkItem, insertInfo);
-}
-
 // Keywords are a 1 to 1 mapping between strings and pairs of (URL, postData).
 // (the postData is not synced, so we ignore it). Sync associates keywords with
 // bookmarks, which is not really accurate. -- We might already have a keyword
 // with that name, or we might already have another bookmark with that URL with
 // a different keyword, etc.
 //
 // If we don't handle those cases by removing the conflicting keywords first,
 // the insertion  will fail, and the keywords will either be wrong, or missing.
@@ -1586,20 +1592,17 @@ async function insertBookmarkMetadata(db
 
   return newItem;
 }
 
 // Determines the Sync record kind for an existing bookmark.
 async function getKindForItem(db, item) {
   switch (item.type) {
     case PlacesUtils.bookmarks.TYPE_FOLDER: {
-      let isLivemark = await getAnno(db, item.guid,
-                                     PlacesUtils.LMANNO_FEEDURI);
-      return isLivemark ? BookmarkSyncUtils.KINDS.LIVEMARK :
-                          BookmarkSyncUtils.KINDS.FOLDER;
+      return BookmarkSyncUtils.KINDS.FOLDER;
     }
     case PlacesUtils.bookmarks.TYPE_BOOKMARK:
       return item.url.protocol == "place:" ?
              BookmarkSyncUtils.KINDS.QUERY :
              BookmarkSyncUtils.KINDS.BOOKMARK;
 
     case PlacesUtils.bookmarks.TYPE_SEPARATOR:
       return BookmarkSyncUtils.KINDS.SEPARATOR;
@@ -1611,55 +1614,24 @@ async function getKindForItem(db, item) 
 // record kind.
 function getTypeForKind(kind) {
   switch (kind) {
     case BookmarkSyncUtils.KINDS.BOOKMARK:
     case BookmarkSyncUtils.KINDS.QUERY:
       return PlacesUtils.bookmarks.TYPE_BOOKMARK;
 
     case BookmarkSyncUtils.KINDS.FOLDER:
-    case BookmarkSyncUtils.KINDS.LIVEMARK:
       return PlacesUtils.bookmarks.TYPE_FOLDER;
 
     case BookmarkSyncUtils.KINDS.SEPARATOR:
       return PlacesUtils.bookmarks.TYPE_SEPARATOR;
   }
   throw new Error(`Unknown bookmark kind: ${kind}`);
 }
 
-// Determines if a livemark should be reinserted. Returns true if `updateInfo`
-// specifies different feed or site URLs; false otherwise.
-var shouldReinsertLivemark = async function(updateInfo) {
-  let hasFeed = updateInfo.hasOwnProperty("feed");
-  let hasSite = updateInfo.hasOwnProperty("site");
-  if (!hasFeed && !hasSite) {
-    return false;
-  }
-  let guid = BookmarkSyncUtils.recordIdToGuid(updateInfo.recordId);
-  let livemark = await PlacesUtils.livemarks.getLivemark({
-    guid,
-  });
-  if (hasFeed) {
-    let feedURI = PlacesUtils.toURI(updateInfo.feed);
-    if (!livemark.feedURI.equals(feedURI)) {
-      return true;
-    }
-  }
-  if (hasSite) {
-    if (!updateInfo.site) {
-      return !!livemark.siteURI;
-    }
-    let siteURI = PlacesUtils.toURI(updateInfo.site);
-    if (!livemark.siteURI || !siteURI.equals(livemark.siteURI)) {
-      return true;
-    }
-  }
-  return false;
-};
-
 async function updateSyncBookmark(db, updateInfo) {
   let guid = BookmarkSyncUtils.recordIdToGuid(updateInfo.recordId);
   let oldBookmarkItem = await PlacesUtils.bookmarks.fetch(guid);
   if (!oldBookmarkItem) {
     throw new Error(`Bookmark with record ID ${
       updateInfo.recordId} does not exist`);
   }
 
@@ -1681,40 +1653,30 @@ async function updateSyncBookmark(db, up
     shouldReinsert = true;
     if (BookmarkSyncLog.level <= Log.Level.Warn) {
       let oldRecordId = BookmarkSyncUtils.guidToRecordId(oldBookmarkItem.guid);
       BookmarkSyncLog.warn(`updateSyncBookmark: Local ${
         oldRecordId} kind = ${oldKind}; remote ${
         updateInfo.recordId} kind = ${
         updateInfo.kind}. Deleting and recreating`);
     }
-  } else if (oldKind == BookmarkSyncUtils.KINDS.LIVEMARK) {
-    // Similarly, if we're changing a livemark's site or feed URL, we need to
-    // reinsert.
-    shouldReinsert = await shouldReinsertLivemark(updateInfo);
-    if (BookmarkSyncLog.level <= Log.Level.Debug) {
-      let oldRecordId = BookmarkSyncUtils.guidToRecordId(oldBookmarkItem.guid);
-      BookmarkSyncLog.debug(`updateSyncBookmark: Local ${
-        oldRecordId} and remote ${
-        updateInfo.recordId} livemarks have different URLs`);
-    }
   }
 
   if (shouldReinsert) {
     if (!updateInfo.hasOwnProperty("dateAdded")) {
       updateInfo.dateAdded = oldBookmarkItem.dateAdded.getTime();
     }
     let newInfo = validateNewBookmark("BookmarkSyncUtils: reinsert",
                                       updateInfo);
     await PlacesUtils.bookmarks.remove({
       guid,
       source: SOURCE_SYNC,
     });
     // A reinsertion likely indicates a confused client, since there aren't
-    // public APIs for changing livemark URLs or an item's kind (e.g., turning
+    // public APIs for changing an item's kind (e.g., turning
     // a folder into a separator while preserving its annos and position).
     // This might be a good case to repair later; for now, we assume Sync has
     // passed a complete record for the new item, and don't try to merge
     // `oldBookmarkItem` with `updateInfo`.
     return insertSyncBookmark(db, newInfo);
   }
 
   let isOrphan = false, requestedParentRecordId;
@@ -1804,27 +1766,24 @@ function validateNewBookmark(name, info)
       recordId: { required: true },
       url: { requiredIf: b => [ BookmarkSyncUtils.KINDS.BOOKMARK,
                                 BookmarkSyncUtils.KINDS.QUERY ].includes(b.kind),
             validIf: b => [ BookmarkSyncUtils.KINDS.BOOKMARK,
                             BookmarkSyncUtils.KINDS.QUERY ].includes(b.kind) },
       parentRecordId: { required: true },
       title: { validIf: b => [ BookmarkSyncUtils.KINDS.BOOKMARK,
                                BookmarkSyncUtils.KINDS.QUERY,
-                               BookmarkSyncUtils.KINDS.FOLDER,
-                               BookmarkSyncUtils.KINDS.LIVEMARK ].includes(b.kind) ||
+                               BookmarkSyncUtils.KINDS.FOLDER ].includes(b.kind) ||
                              b.title === "" },
       query: { validIf: b => b.kind == BookmarkSyncUtils.KINDS.QUERY },
       folder: { validIf: b => b.kind == BookmarkSyncUtils.KINDS.QUERY },
       tags: { validIf: b => [ BookmarkSyncUtils.KINDS.BOOKMARK,
                               BookmarkSyncUtils.KINDS.QUERY ].includes(b.kind) },
       keyword: { validIf: b => [ BookmarkSyncUtils.KINDS.BOOKMARK,
                                  BookmarkSyncUtils.KINDS.QUERY ].includes(b.kind) },
-      feed: { validIf: b => b.kind == BookmarkSyncUtils.KINDS.LIVEMARK },
-      site: { validIf: b => b.kind == BookmarkSyncUtils.KINDS.LIVEMARK },
       dateAdded: { required: false },
     });
 
   return insertInfo;
 }
 
 async function fetchGuidsWithAnno(db, anno, val) {
   let rows = await db.executeCached(`
@@ -1832,28 +1791,16 @@ async function fetchGuidsWithAnno(db, an
     JOIN moz_anno_attributes n ON n.id = a.anno_attribute_id
     JOIN moz_bookmarks b ON b.id = a.item_id
     WHERE n.name = :anno AND
           a.content = :val`,
     { anno, val });
   return rows.map(row => row.getResultByName("guid"));
 }
 
-// Returns the value of an item's annotation, or `null` if it's not set.
-async function getAnno(db, guid, anno) {
-  let rows = await db.executeCached(`
-    SELECT a.content FROM moz_items_annos a
-    JOIN moz_anno_attributes n ON n.id = a.anno_attribute_id
-    JOIN moz_bookmarks b ON b.id = a.item_id
-    WHERE b.guid = :guid AND
-          n.name = :anno`,
-    { guid, anno });
-  return rows.length ? rows[0].getResultByName("content") : null;
-}
-
 function tagItem(item, tags) {
   if (!item.url) {
     return [];
   }
 
   // Remove leading and trailing whitespace, then filter out empty tags.
   let newTags = tags ? tags.map(tag => tag.trim()).filter(Boolean) : [];
 
@@ -1875,19 +1822,19 @@ function tagItem(item, tags) {
 // but doesn't know about additional livemark properties. We check this to avoid
 // having it throw in case we only pass properties like `{ guid, feedURI }`.
 function shouldUpdateBookmark(bookmarkInfo) {
   return bookmarkInfo.hasOwnProperty("parentGuid") ||
          bookmarkInfo.hasOwnProperty("title") ||
          bookmarkInfo.hasOwnProperty("url");
 }
 
-// Converts a Places bookmark or livemark to a Sync bookmark. This function
-// maps Places GUIDs to record IDs and filters out extra Places properties like
-// date added, last modified, and index.
+// Converts a Places bookmark to a Sync bookmark. This function maps Places
+// GUIDs to record IDs and filters out extra Places properties like date added,
+// last modified, and index.
 async function placesBookmarkToSyncBookmark(db, bookmarkItem) {
   let item = {};
 
   for (let prop in bookmarkItem) {
     switch (prop) {
       // Record IDs are identical to Places GUIDs for all items except roots.
       case "guid":
         item.recordId = BookmarkSyncUtils.guidToRecordId(bookmarkItem.guid);
@@ -1907,28 +1854,16 @@ async function placesBookmarkToSyncBookm
       case "title":
       case "url":
         item[prop] = bookmarkItem[prop];
         break;
 
       case "dateAdded":
         item[prop] = new Date(bookmarkItem[prop]).getTime();
         break;
-
-      // Livemark objects contain additional properties. The feed URL is
-      // required; the site URL is optional.
-      case "feedURI":
-        item.feed = new URL(bookmarkItem.feedURI.spec);
-        break;
-
-      case "siteURI":
-        if (bookmarkItem.siteURI) {
-          item.site = new URL(bookmarkItem.siteURI.spec);
-        }
-        break;
     }
   }
 
   return item;
 }
 
 // Converts a Sync bookmark object to a Places bookmark or livemark object.
 // This function maps record IDs to Places GUIDs, and filters out extra Sync
@@ -1954,36 +1889,25 @@ function syncBookmarkToPlacesBookmark(in
         bookmarkInfo.dateAdded = new Date(info.dateAdded);
         break;
 
       case "parentRecordId":
         bookmarkInfo.parentGuid =
           BookmarkSyncUtils.recordIdToGuid(info.parentRecordId);
         // Instead of providing an index, Sync reorders children at the end of
         // the sync using `BookmarkSyncUtils.order`. We explicitly specify the
-        // default index here to prevent `PlacesUtils.bookmarks.update` and
-        // `PlacesUtils.livemarks.addLivemark` from throwing.
+        // default index here to prevent `PlacesUtils.bookmarks.update` from
+        // throwing.
         bookmarkInfo.index = PlacesUtils.bookmarks.DEFAULT_INDEX;
         break;
 
       case "title":
       case "url":
         bookmarkInfo[prop] = info[prop];
         break;
-
-      // Livemark-specific properties.
-      case "feed":
-        bookmarkInfo.feedURI = PlacesUtils.toURI(info.feed);
-        break;
-
-      case "site":
-        if (info.site) {
-          bookmarkInfo.siteURI = PlacesUtils.toURI(info.site);
-        }
-        break;
     }
   }
 
   return bookmarkInfo;
 }
 
 // Creates and returns a Sync bookmark object containing the bookmark's
 // tags, keyword.
@@ -2018,38 +1942,16 @@ async function fetchFolderItem(db, bookm
   let childGuids = await fetchChildGuids(db, bookmarkItem.guid);
   item.childRecordIds = childGuids.map(guid =>
     BookmarkSyncUtils.guidToRecordId(guid)
   );
 
   return item;
 }
 
-// Creates and returns a Sync bookmark object containing the livemark's
-// children (none), feed URI, and site URI.
-async function fetchLivemarkItem(db, bookmarkItem) {
-  let item = await placesBookmarkToSyncBookmark(db, bookmarkItem);
-
-  if (!item.title) {
-    item.title = "";
-  }
-
-  let feedAnno = await getAnno(db, bookmarkItem.guid,
-                               PlacesUtils.LMANNO_FEEDURI);
-  item.feed = new URL(feedAnno);
-
-  let siteAnno = await getAnno(db, bookmarkItem.guid,
-                               PlacesUtils.LMANNO_SITEURI);
-  if (siteAnno) {
-    item.site = new URL(siteAnno);
-  }
-
-  return item;
-}
-
 // Creates and returns a Sync bookmark object containing the query's tag
 // folder name.
 async function fetchQueryItem(db, bookmarkItem) {
   let item = await placesBookmarkToSyncBookmark(db, bookmarkItem);
 
   let params = new URLSearchParams(bookmarkItem.url.pathname);
   let tags = params.getAll("tag");
   if (tags.length == 1) {
@@ -2100,42 +2002,54 @@ function addRowToChangeRecords(row, chan
 }
 
 /**
  * Queries the database for synced bookmarks and tombstones, and returns a
  * changeset for the Sync bookmarks engine.
  *
  * @param db
  *        The Sqlite.jsm connection handle.
+ * @param forGuids
+ *        Fetch Sync tracking information for only the requested GUIDs.
  * @return {Promise} resolved once all items have been fetched.
  * @resolves to an object containing records for changed bookmarks, keyed by
  *           the record ID.
  */
-var pullSyncChanges = async function(db) {
+var pullSyncChanges = async function(db, forGuids = []) {
   let changeRecords = {};
 
+  let itemConditions = ["syncChangeCounter >= 1"];
+  let tombstoneConditions = ["1 = 1"];
+  if (forGuids.length) {
+    let restrictToGuids = `guid IN (${forGuids.map(guid =>
+      JSON.stringify(guid)).join(",")})`;
+    itemConditions.push(restrictToGuids);
+    tombstoneConditions.push(restrictToGuids);
+  }
+
   let rows = await db.executeCached(`
     WITH RECURSIVE
     syncedItems(id, guid, modified, syncChangeCounter, syncStatus) AS (
       SELECT b.id, b.guid, b.lastModified, b.syncChangeCounter, b.syncStatus
        FROM moz_bookmarks b
        WHERE b.guid IN ('menu________', 'toolbar_____', 'unfiled_____',
                         'mobile______')
       UNION ALL
       SELECT b.id, b.guid, b.lastModified, b.syncChangeCounter, b.syncStatus
       FROM moz_bookmarks b
       JOIN syncedItems s ON b.parent = s.id
     )
     SELECT guid, modified, syncChangeCounter, syncStatus, 0 AS tombstone
     FROM syncedItems
-    WHERE syncChangeCounter >= 1
+    WHERE ${itemConditions.join(" AND ")}
     UNION ALL
     SELECT guid, dateRemoved AS modified, 1 AS syncChangeCounter,
            :deletedSyncStatus, 1 AS tombstone
-    FROM moz_bookmarks_deleted`,
+    FROM moz_bookmarks_deleted
+    WHERE ${tombstoneConditions.join(" AND ")}`,
     { deletedSyncStatus: PlacesUtils.bookmarks.SYNC_STATUS.NORMAL });
   for (let row of rows) {
     addRowToChangeRecords(row, changeRecords);
   }
 
   return changeRecords;
 };
 
--- a/toolkit/components/places/PlacesTransactions.jsm
+++ b/toolkit/components/places/PlacesTransactions.jsm
@@ -83,17 +83,17 @@ var EXPORTED_SYMBOLS = ["PlacesTransacti
  * reveal once the transaction is executed.
  *
  * Executing Transactions (the |transact| method of transactions)
  * --------------------------------------------------------------
  * Once a transaction is created, you must call its |transact| method for it to
  * be executed and take effect.  |transact| is an asynchronous method that takes
  * no arguments, and returns a promise that resolves once the transaction is
  * executed.  Executing one of the transactions for creating items (NewBookmark,
- * NewFolder, NewSeparator or NewLivemark) resolve to the new item's GUID.
+ * NewFolder, NewSeparator) resolve to the new item's GUID.
  * There's no resolution value for other transactions.
  * If a transaction fails to execute, |transact| rejects and the transactions
  * history is not affected.
  *
  * |transact| throws if it's called more than once (successfully or not) on the
  * same transaction object.
  *
  * Batches
@@ -940,33 +940,16 @@ DefineTransaction.defineArrayInputProp("
  *       always ignored.  The index property is ignored for all items but the
  *       root one.
  * @return {Promise}
  * @resolves to the guid of the new item.
  */
 // TODO: Replace most of this with insertTree.
 function createItemsFromBookmarksTree(tree, restoring = false,
                                       excludingAnnotations = []) {
-  function extractLivemarkDetails(annos) {
-    let feedURI = null, siteURI = null;
-    annos = annos.filter(anno => {
-      switch (anno.name) {
-        case PlacesUtils.LMANNO_FEEDURI:
-          feedURI = Services.io.newURI(anno.value);
-          return false;
-        case PlacesUtils.LMANNO_SITEURI:
-          siteURI = Services.io.newURI(anno.value);
-          return false;
-        default:
-          return true;
-      }
-    });
-    return [feedURI, siteURI, annos];
-  }
-
   async function createItem(item,
                             parentGuid,
                             index = PlacesUtils.bookmarks.DEFAULT_INDEX) {
     let guid;
     let info = { parentGuid, index };
     if (restoring) {
       info.guid = item.guid;
       info.dateAdded = PlacesUtils.toDate(item.dateAdded);
@@ -988,43 +971,27 @@ function createItemsFromBookmarksTree(tr
         }
         if ("tags" in item) {
           PlacesUtils.tagging.tagURI(Services.io.newURI(item.uri),
                                      item.tags.split(","));
         }
         break;
       }
       case PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER: {
-        // Either a folder or a livemark
-        let feedURI, siteURI;
-        [feedURI, siteURI, annos] = extractLivemarkDetails(annos);
-        if (!feedURI) {
-          info.type = PlacesUtils.bookmarks.TYPE_FOLDER;
-          if (typeof(item.title) == "string")
-            info.title = item.title;
-          guid = (await PlacesUtils.bookmarks.insert(info)).guid;
-          if ("children" in item) {
-            for (let child of item.children) {
-              await createItem(child, guid);
-            }
+        info.type = PlacesUtils.bookmarks.TYPE_FOLDER;
+        if (typeof(item.title) == "string")
+          info.title = item.title;
+        guid = (await PlacesUtils.bookmarks.insert(info)).guid;
+        if ("children" in item) {
+          for (let child of item.children) {
+            await createItem(child, guid);
           }
-          if (restoring)
-            shouldResetLastModified = true;
-        } else {
-          info.parentId = await PlacesUtils.promiseItemId(parentGuid);
-          info.feedURI = feedURI;
-          info.siteURI = siteURI;
-          if (info.dateAdded)
-            info.dateAdded = PlacesUtils.toPRTime(info.dateAdded);
-          if (info.lastModified)
-            info.lastModified = PlacesUtils.toPRTime(info.lastModified);
-          if (typeof(item.title) == "string")
-            info.title = item.title;
-          guid = (await PlacesUtils.livemarks.addLivemark(info)).guid;
         }
+        if (restoring)
+          shouldResetLastModified = true;
         break;
       }
       case PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR: {
         info.type = PlacesUtils.bookmarks.TYPE_SEPARATOR;
         guid = (await PlacesUtils.bookmarks.insert(info)).guid;
         break;
       }
     }
@@ -1193,59 +1160,16 @@ PT.NewSeparator.prototype = Object.seal(
     info = await PlacesUtils.bookmarks.insert(info);
     this.undo = PlacesUtils.bookmarks.remove.bind(PlacesUtils.bookmarks, info);
     this.redo = PlacesUtils.bookmarks.insert.bind(PlacesUtils.bookmarks, info);
     return info.guid;
   },
 });
 
 /**
- * Transaction for creating a live bookmark (see mozIAsyncLivemarks for the
- * semantics).
- *
- * Required Input Properties: feedUrl, title, parentGuid.
- * Optional Input Properties: siteUrl, index, annotations.
- *
- * When this transaction is executed, it's resolved to the new livemark's
- * GUID.
- */
-PT.NewLivemark = DefineTransaction(["feedUrl", "title", "parentGuid"],
-                                   ["siteUrl", "index", "annotations"]);
-PT.NewLivemark.prototype = Object.seal({
-  async execute({ feedUrl, title, parentGuid, siteUrl, index, annotations }) {
-    let livemarkInfo = { title,
-                         feedURI: Services.io.newURI(feedUrl.href),
-                         siteURI: siteUrl ? Services.io.newURI(siteUrl.href) : null,
-                         index,
-                         parentGuid};
-    let createItem = async function() {
-      let livemark = await PlacesUtils.livemarks.addLivemark(livemarkInfo);
-      if (annotations.length > 0) {
-        PlacesUtils.setAnnotationsForItem(livemark.id, annotations,
-          Ci.nsINavBookmarksService.SOURCE_DEFAULT, true);
-      }
-      return livemark;
-    };
-
-    let livemark = await createItem();
-    livemarkInfo.guid = livemark.guid;
-    livemarkInfo.dateAdded = livemark.dateAdded;
-    livemarkInfo.lastModified = livemark.lastModified;
-
-    this.undo = async function() {
-      await PlacesUtils.livemarks.removeLivemark(livemark);
-    };
-    this.redo = async function() {
-      livemark = await createItem();
-    };
-    return livemark.guid;
-  },
-});
-
-/**
  * Transaction for moving an item.
  *
  * Required Input Properties: guid, newParentGuid.
  * Optional Input Properties  newIndex.
  */
 PT.Move = DefineTransaction(["guids", "newParentGuid"], ["newIndex"]);
 PT.Move.prototype = Object.seal({
   async execute({ guids, newParentGuid, newIndex }) {
--- a/toolkit/components/places/PlacesUtils.jsm
+++ b/toolkit/components/places/PlacesUtils.jsm
@@ -121,29 +121,26 @@ function getAnnotationsForItem(aItemId) 
   return annos;
 }
 
 /**
  * Serializes the given node in JSON format.
  *
  * @param aNode
  *        An nsINavHistoryResultNode
- * @param aIsLivemark
- *        Whether the node represents a livemark.
  */
-function serializeNode(aNode, aIsLivemark) {
+function serializeNode(aNode) {
   let data = {};
 
   data.title = aNode.title;
   // The id is no longer used for copying within the same instance/session of
   // Firefox as of at least 61. However, we keep the id for now to maintain
   // backwards compat of drag and drop with older Firefox versions.
   data.id = aNode.itemId;
   data.itemGuid = aNode.bookmarkGuid;
-  data.livemark = aIsLivemark;
   // Add an instanceId so we can tell which instance of an FF session the data
   // is coming from.
   data.instanceId = PlacesUtils.instanceId;
 
   let guid = aNode.bookmarkGuid;
 
   // Some nodes, e.g. the unfiled/menu/toolbar ones can have a virtual guid, so
   // we ignore any that are a folder shortcut. These will be handled below.
@@ -918,23 +915,19 @@ var PlacesUtils = {
   /**
    * String-wraps a result node according to the rules of the specified
    * content type for copy or move operations.
    *
    * @param   aNode
    *          The Result node to wrap (serialize)
    * @param   aType
    *          The content type to serialize as
-   * @param   [optional] aFeedURI
-   *          Used instead of the node's URI if provided.
-   *          This is useful for wrapping a livemark as TYPE_X_MOZ_URL,
-   *          TYPE_HTML or TYPE_UNICODE.
    * @return  A string serialization of the node
    */
-  wrapNode(aNode, aType, aFeedURI) {
+  wrapNode(aNode, aType) {
     // when wrapping a node, we want all the items, even if the original
     // query options are excluding them.
     // This can happen when copying from the left hand pane of the bookmarks
     // organizer.
     // @return [node, shouldClose]
     function gatherDataFromNode(node, gatherDataFunc) {
       if (PlacesUtils.nodeIsFolder(node) &&
           node.type != Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT &&
@@ -955,20 +948,16 @@ var PlacesUtils = {
                              .replace(/>/g, "&gt;")
                              .replace(/</g, "&lt;")
                              .replace(/"/g, "&quot;")
                              .replace(/'/g, "&apos;");
 
       // escape out potential HTML in the title
       let escapedTitle = node.title ? htmlEscape(node.title) : "";
 
-      if (aFeedURI) {
-        return `<A HREF="${aFeedURI}">${escapedTitle}</A>${NEWLINE}`;
-      }
-
       if (PlacesUtils.nodeIsContainer(node)) {
         asContainer(node);
         let wasOpen = node.containerOpen;
         if (!wasOpen)
           node.containerOpen = true;
 
         let childString = "<DL><DT>" + escapedTitle + "</DT>" + NEWLINE;
         let cc = node.childCount;
@@ -985,20 +974,16 @@ var PlacesUtils = {
       if (PlacesUtils.nodeIsURI(node))
         return `<A HREF="${node.uri}">${escapedTitle}</A>${NEWLINE}`;
       if (PlacesUtils.nodeIsSeparator(node))
         return "<HR>" + NEWLINE;
       return "";
     }
 
     function gatherDataText(node) {
-      if (aFeedURI) {
-        return aFeedURI;
-      }
-
       if (PlacesUtils.nodeIsContainer(node)) {
         asContainer(node);
         let wasOpen = node.containerOpen;
         if (!wasOpen)
           node.containerOpen = true;
 
         let childString = node.title + NEWLINE;
         let cc = node.childCount;
@@ -1017,21 +1002,22 @@ var PlacesUtils = {
       return "";
     }
 
     switch (aType) {
       case this.TYPE_X_MOZ_PLACE:
       case this.TYPE_X_MOZ_PLACE_SEPARATOR:
       case this.TYPE_X_MOZ_PLACE_CONTAINER: {
         // Serialize the node to JSON.
-        return serializeNode(aNode, aFeedURI);
+        return serializeNode(aNode);
       }
       case this.TYPE_X_MOZ_URL: {
-        if (aFeedURI || PlacesUtils.nodeIsURI(aNode))
-          return (aFeedURI || aNode.uri) + NEWLINE + aNode.title;
+        if (PlacesUtils.nodeIsURI(aNode)) {
+          return aNode.uri + NEWLINE + aNode.title;
+        }
         if (PlacesUtils.nodeIsContainer(aNode)) {
           return PlacesUtils.getURLsForContainerNode(aNode)
             .map(item => item.uri + "\n" + item.title)
             .join("\n");
         }
         return "";
       }
       case this.TYPE_HTML: {
--- a/toolkit/components/places/SyncedBookmarksMirror.jsm
+++ b/toolkit/components/places/SyncedBookmarksMirror.jsm
@@ -1246,36 +1246,26 @@ class SyncedBookmarksMirror {
              /* Map Places item types to Sync record kinds. */
              (CASE s.type
                 WHEN :bookmarkType THEN (
                   CASE SUBSTR((SELECT h.url FROM moz_places h
                                WHERE h.id = s.placeId), 1, 6)
                   /* Queries are bookmarks with a "place:" URL scheme. */
                   WHEN 'place:' THEN :queryKind
                   ELSE :bookmarkKind END)
-                WHEN :folderType THEN (
-                  CASE WHEN EXISTS(
-                    /* Livemarks are folders with a feed URL annotation. */
-                    SELECT 1 FROM moz_items_annos a
-                    JOIN moz_anno_attributes n ON n.id = a.anno_attribute_id
-                    WHERE a.item_id = s.id AND
-                          n.name = :feedURLAnno
-                  ) THEN :livemarkKind
-                  ELSE :folderKind END)
+                WHEN :folderType THEN :folderKind
                 ELSE :separatorKind END) AS kind,
              s.lastModified / 1000 AS localModified, s.syncChangeCounter,
              s.level, s.isSyncable
       FROM localItems s
       ORDER BY s.level, s.parentId, s.position`,
       { bookmarkType: PlacesUtils.bookmarks.TYPE_BOOKMARK,
         queryKind: SyncedBookmarksMirror.KIND.QUERY,
         bookmarkKind: SyncedBookmarksMirror.KIND.BOOKMARK,
         folderType: PlacesUtils.bookmarks.TYPE_FOLDER,
-        feedURLAnno: PlacesUtils.LMANNO_FEEDURI,
-        livemarkKind: SyncedBookmarksMirror.KIND.LIVEMARK,
         folderKind: SyncedBookmarksMirror.KIND.FOLDER,
         separatorKind: SyncedBookmarksMirror.KIND.SEPARATOR });
 
     for await (let row of yieldingIterator(itemRows)) {
       let parentGuid = row.getResultByName("parentGuid");
       let node = BookmarkNode.fromLocalRow(row, localTimeSeconds);
       localTree.insert(parentGuid, node);
     }
@@ -1641,39 +1631,16 @@ class SyncedBookmarksMirror {
             bookmarkCleartext.tags = tags;
           }
           changeRecords[recordId] = new BookmarkChangeRecord(
             syncChangeCounter, bookmarkCleartext);
           continue;
         }
 
         case PlacesUtils.bookmarks.TYPE_FOLDER: {
-          let feedURLHref = row.getResultByName("feedURL");
-          if (feedURLHref) {
-            // Places stores livemarks as folders with feed and site URL annos.
-            // See bug 1072833 for discussion about changing them to queries.
-            let livemarkCleartext = {
-              id: recordId,
-              type: "livemark",
-              parentid: parentRecordId,
-              hasDupe: true,
-              parentName: row.getResultByName("parentTitle"),
-              dateAdded: row.getResultByName("dateAdded") || undefined,
-              title: row.getResultByName("title"),
-              feedUri: feedURLHref,
-            };
-            let siteURLHref = row.getResultByName("siteURL");
-            if (siteURLHref) {
-              livemarkCleartext.siteUri = siteURLHref;
-            }
-            changeRecords[recordId] = new BookmarkChangeRecord(
-              syncChangeCounter, livemarkCleartext);
-            continue;
-          }
-
           let folderCleartext = {
             id: recordId,
             type: "folder",
             parentid: parentRecordId,
             hasDupe: true,
             parentName: row.getResultByName("parentTitle"),
             dateAdded: row.getResultByName("dateAdded") || undefined,
             title: row.getResultByName("title"),
@@ -2677,19 +2644,28 @@ async function inflateTree(tree, pseudoT
   if (nodes) {
     for (let node of nodes) {
       await maybeYield();
       node.level = parentNode.level + 1;
       // See `LocalItemsSQLFragment` for a more detailed explanation about
       // syncable and non-syncable items. Non-syncable items might be
       // reuploaded by Android after a node reassignment, or orphaned on the
       // server.
-      node.isSyncable = parentNode == tree.root ?
-        PlacesUtils.bookmarks.userContentRoots.includes(node.guid) :
-        parentNode.isSyncable;
+      if (parentNode == tree.root) {
+        node.isSyncable = PlacesUtils.bookmarks.userContentRoots.includes(node.guid);
+      } else if (node.kind == SyncedBookmarksMirror.KIND.LIVEMARK) {
+        // Places no longer supports livemarks, so we flag unmerged remote
+        // livemarks as non-syncable. This will delete them locally, upload
+        // tombstones, and reupload their parents. Note that we *don't* flag
+        // livemarks that have already been synced, to minimize data loss.
+        // This is only for livemarks that we haven't downloaded yet.
+        node.isSyncable = false;
+      } else {
+        node.isSyncable = parentNode.isSyncable;
+      }
       tree.insert(parentNode.guid, node);
       await inflateTree(tree, pseudoTree, node);
     }
   }
 }
 
 /**
  * Measures and logs the time taken to execute a function, using a monotonic
@@ -2969,30 +2945,16 @@ class BookmarkNode {
     // can cause it to flip kinds - and webextensions are able to change the
     // URL of any bookmark.
     if ((this.kind == SyncedBookmarksMirror.KIND.BOOKMARK &&
          remoteNode.kind == SyncedBookmarksMirror.KIND.QUERY) ||
         (this.kind == SyncedBookmarksMirror.KIND.QUERY &&
          remoteNode.kind == SyncedBookmarksMirror.KIND.BOOKMARK)) {
       return true;
     }
-    // A local folder can become a livemark as the remote may have synced
-    // as a folder before the annotation was added. However, we don't allow
-    // a local livemark to "downgrade" to a folder.
-    // We allow merging local folders and remote livemarks because Places
-    // stores livemarks as empty folders with feed and site URL annotations.
-    // The livemarks service first inserts the folder, and *then* sets
-    // annotations. Since this isn't wrapped in a transaction, we might sync
-    // before the annotations are set, and upload a folder record instead
-    // of a livemark record (bug 632287), then replace the folder with a
-    // livemark on the next sync.
-    if (this.kind == SyncedBookmarksMirror.KIND.FOLDER &&
-        remoteNode.kind == SyncedBookmarksMirror.KIND.LIVEMARK) {
-      return true;
-    }
     return false;
   }
 
   /**
    * Generates a human-readable, ASCII art representation of the node and its
    * descendants. This is useful for visualizing the tree structure in trace
    * logs.
    *
@@ -4429,17 +4391,16 @@ class BookmarkObserverRecorder {
    * URLs. This is called outside the merge transaction.
    */
   async notifyAll() {
     await this.noteAllChanges();
     if (this.shouldInvalidateKeywords) {
       await PlacesUtils.keywords.invalidateCachedKeywords();
     }
     await this.notifyBookmarkObservers();
-    await PlacesUtils.livemarks.invalidateCachedLivemarks();
     await this.updateFrecencies();
   }
 
   async updateFrecencies() {
     MirrorLog.trace("Recalculating frecencies for new URLs");
     await this.db.execute(`
       UPDATE moz_places SET
         frecency = CALCULATE_FRECENCY(id)
--- a/toolkit/components/places/mozIAsyncLivemarks.idl
+++ b/toolkit/components/places/mozIAsyncLivemarks.idl
@@ -10,29 +10,16 @@ interface mozILivemarkInfo;
 interface mozILivemark;
 
 interface nsINavHistoryResultObserver;
 
 [scriptable, uuid(672387b7-a75d-4e8f-9b49-5c1dcbfff46b)]
 interface mozIAsyncLivemarks : nsISupports
 {
   /**
-   * Creates a new livemark
-   *
-   * @param aLivemarkInfo
-   *        mozILivemarkInfo object containing at least title, parentId,
-   *        index and feedURI of the livemark to create.
-   *
-   * @return {Promise}
-   * @throws NS_ERROR_INVALID_ARG if the supplied information is insufficient
-   *         for the creation.
-   */
-  jsval addLivemark(in jsval aLivemarkInfo);
-
-  /**
    * Removes an existing livemark.
    *
    * @param aLivemarkInfo
    *        mozILivemarkInfo object containing either an id or a guid of the
    *        livemark to remove.
    *
    * @return {Promise}
    * @throws NS_ERROR_INVALID_ARG if the id/guid is invalid.
--- a/toolkit/components/places/nsLivemarkService.js
+++ b/toolkit/components/places/nsLivemarkService.js
@@ -156,88 +156,16 @@ LivemarkService.prototype = {
         // No need to restart the reload timer on shutdown.
         keepReloading: false,
       }).catch(Cu.reportError);
     }
   },
 
   // mozIAsyncLivemarks
 
-  addLivemark(aLivemarkInfo) {
-    if (!aLivemarkInfo) {
-      throw new Components.Exception("Invalid arguments", Cr.NS_ERROR_INVALID_ARG);
-    }
-    let hasParentId = "parentId" in aLivemarkInfo;
-    let hasParentGuid = "parentGuid" in aLivemarkInfo;
-    let hasIndex = "index" in aLivemarkInfo;
-    // Must provide at least non-null parent guid/id, index and feedURI.
-    if ((!hasParentId && !hasParentGuid) ||
-        (hasParentId && aLivemarkInfo.parentId < 1) ||
-        (hasParentGuid && !/^[a-zA-Z0-9\-_]{12}$/.test(aLivemarkInfo.parentGuid)) ||
-        (hasIndex && aLivemarkInfo.index < Ci.nsINavBookmarksService.DEFAULT_INDEX) ||
-        !(aLivemarkInfo.feedURI instanceof Ci.nsIURI) ||
-        (aLivemarkInfo.siteURI && !(aLivemarkInfo.siteURI instanceof Ci.nsIURI)) ||
-        (aLivemarkInfo.guid && !/^[a-zA-Z0-9\-_]{12}$/.test(aLivemarkInfo.guid))) {
-      throw new Components.Exception("Invalid arguments", Cr.NS_ERROR_INVALID_ARG);
-    }
-
-    return this._withLivemarksMap(async livemarksMap => {
-      if (!aLivemarkInfo.parentGuid)
-        aLivemarkInfo.parentGuid = await PlacesUtils.promiseItemGuid(aLivemarkInfo.parentId);
-
-      // Disallow adding a livemark inside another livemark.
-      if (livemarksMap.has(aLivemarkInfo.parentGuid)) {
-        throw new Components.Exception("Cannot create a livemark inside a livemark", Cr.NS_ERROR_INVALID_ARG);
-      }
-
-      // Create a new livemark.
-      let folder = await PlacesUtils.bookmarks.insert({
-        type: PlacesUtils.bookmarks.TYPE_FOLDER,
-        parentGuid: aLivemarkInfo.parentGuid,
-        title: aLivemarkInfo.title,
-        index: aLivemarkInfo.index,
-        guid: aLivemarkInfo.guid,
-        dateAdded: toDate(aLivemarkInfo.dateAdded) || toDate(aLivemarkInfo.lastModified),
-        source: aLivemarkInfo.source,
-      });
-
-      // Set feed and site URI annotations.
-      let id = await PlacesUtils.promiseItemId(folder.guid);
-
-      // Create the internal Livemark object.
-      let livemark = new Livemark({ id,
-                                    title:        folder.title,
-                                    parentGuid:   folder.parentGuid,
-                                    parentId:     await PlacesUtils.promiseItemId(folder.parentGuid),
-                                    index:        folder.index,
-                                    feedURI:      aLivemarkInfo.feedURI,
-                                    siteURI:      aLivemarkInfo.siteURI,
-                                    guid:         folder.guid,
-                                    dateAdded:    toPRTime(folder.dateAdded),
-                                    lastModified: toPRTime(folder.lastModified),
-                                  });
-
-      livemark.writeFeedURI(aLivemarkInfo.feedURI, aLivemarkInfo.source);
-      if (aLivemarkInfo.siteURI) {
-        livemark.writeSiteURI(aLivemarkInfo.siteURI, aLivemarkInfo.source);
-      }
-
-      if (aLivemarkInfo.lastModified) {
-        await PlacesUtils.bookmarks.update({ guid: folder.guid,
-                                             lastModified: toDate(aLivemarkInfo.lastModified),
-                                             source: aLivemarkInfo.source });
-        livemark.lastModified = aLivemarkInfo.lastModified;
-      }
-
-      livemarksMap.set(folder.guid, livemark);
-
-      return livemark;
-    });
-  },
-
   removeLivemark(aLivemarkInfo) {
     if (!aLivemarkInfo) {
       throw new Components.Exception("Invalid arguments", Cr.NS_ERROR_INVALID_ARG);
     }
     // Accept either a guid or an id.
     let hasGuid = "guid" in aLivemarkInfo;
     let hasId = "id" in aLivemarkInfo;
     if ((hasGuid && !/^[a-zA-Z0-9\-_]{12}$/.test(aLivemarkInfo.guid)) ||
@@ -493,25 +421,16 @@ Livemark.prototype = {
   set status(val) {
     if (this._status != val) {
       this._status = val;
       this._invalidateRegisteredContainers();
     }
     return this._status;
   },
 
-  writeFeedURI(aFeedURI, aSource) {
-    PlacesUtils.annotations
-               .setItemAnnotation(this.id, PlacesUtils.LMANNO_FEEDURI,
-                                  aFeedURI.spec,
-                                  0, PlacesUtils.annotations.EXPIRE_NEVER,
-                                  aSource, true);
-    this.feedURI = aFeedURI;
-  },
-
   writeSiteURI(aSiteURI, aSource) {
     if (!aSiteURI) {
       PlacesUtils.annotations.removeItemAnnotation(this.id,
                                                    PlacesUtils.LMANNO_SITEURI,
                                                    aSource);
       this.siteURI = null;
       return;
     }
--- a/toolkit/components/places/tests/chrome/chrome.ini
+++ b/toolkit/components/places/tests/chrome/chrome.ini
@@ -1,14 +1,7 @@
 [DEFAULT]
 support-files = head.js
 
-[test_303567.xul]
-[test_341972a.xul]
-[test_341972b.xul]
-[test_342484.xul]
 [test_371798.xul]
-[test_381357.xul]
 [test_favicon_annotations.xul]
-[test_reloadLivemarks.xul]
-skip-if = verify
 [test_browser_disableglobalhistory.xul]
 support-files = browser_disableglobalhistory.xul
deleted file mode 100644
--- a/toolkit/components/places/tests/chrome/test_303567.xul
+++ /dev/null
@@ -1,118 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet
-  href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
-<window title="Add Bad Livemarks"
-  xmlns:html="http://www.w3.org/1999/xhtml"
-  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-  onload="runTest()">
-  <script type="application/javascript"
-   src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-
-  <body xmlns="http://www.w3.org/1999/xhtml" />
-
-<script type="application/javascript">
-<![CDATA[
-// Test that for feeds with items that have no link:
-//   * the link-less items are present in the database.
-//   * the feed's site URI is substituted for each item's link.
-SimpleTest.waitForExplicitFinish();
-
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
-ChromeUtils.import("resource://gre/modules/PlacesUtils.jsm");
-
-const LIVEMARKS = [
-  { feedURI: NetUtil.newURI("http://mochi.test:8888/tests/toolkit/components/places/tests/chrome/link-less-items.rss"),
-    siteURI: NetUtil.newURI("http://mochi.test:8888/"),
-    urls: [
-      "http://feed-item-link.com/",
-      "http://feed-link.com/",
-      "http://feed-item-link.com/",
-    ],
-    message: "Ensure link-less livemark item picked up site uri.",
-  },
-  { feedURI: NetUtil.newURI("http://mochi.test:8888/tests/toolkit/components/places/tests/chrome/link-less-items-no-site-uri.rss"),
-    siteURI: null,
-    urls: [
-      "http://feed-item-link.com/",
-      "http://feed-item-link.com/",
-    ],
-    message: "Ensure livemark item links did not inherit site uri."
-  },  
-];
-
-function runTest()
-{
-  let loadCount = 0;
-
-  function testLivemark(aLivemarkData) {
-    PlacesUtils.livemarks.addLivemark(
-      { title: "foo"
-      , parentGuid: PlacesUtils.bookmarks.toolbarGuid
-      , feedURI: aLivemarkData.feedURI
-      , siteURI: aLivemarkData.siteURI
-      })
-      .then(function (aLivemark) {
-        is (aLivemark.feedURI.spec, aLivemarkData.feedURI.spec,
-            "Get correct feedURI");
-        if (aLivemarkData.siteURI) {
-          is (aLivemark.siteURI.spec, aLivemarkData.siteURI.spec,
-              "Get correct siteURI");
-        }
-        else {
-          is (aLivemark.siteURI, null, "Get correct siteURI");
-        }
-
-        waitForLivemarkLoad(aLivemark, function (aLivemark) {
-          let nodes = aLivemark.getNodesForContainer({});
-          is(nodes.length, aLivemarkData.urls.length,
-             "Ensure all the livemark items were created.");
-          aLivemarkData.urls.forEach(function (aUrl, aIndex) {
-            let node = nodes[aIndex];
-            is(node.uri, aUrl, aLivemarkData.message);
-          });
-
-          PlacesUtils.livemarks.removeLivemark(aLivemark).then(() => {
-            if (++loadCount == LIVEMARKS.length)
-              SimpleTest.finish();
-          });
-        });
-      }, function () {
-        is(true, false, "Should not fail adding a livemark");
-      }
-    );
-  }
-
-  LIVEMARKS.forEach(testLivemark);
-}
-
-function waitForLivemarkLoad(aLivemark, aCallback) {
-  // Don't need a real node here.
-  let node = {};
-  let resultObserver = {
-    nodeInserted: function() {},
-    nodeRemoved: function() {},
-    nodeAnnotationChanged: function() {},
-    nodeTitleChanged: function() {},
-    nodeHistoryDetailsChanged: function() {},
-    nodeMoved: function() {},
-    ontainerStateChanged: function () {},
-    sortingChanged: function() {},
-    batching: function() {},
-    invalidateContainer: function(node) {
-      isnot(aLivemark.status, Ci.mozILivemark.STATUS_FAILED,
-            "Loading livemark should success");
-      if (aLivemark.status == Ci.mozILivemark.STATUS_READY) {
-        aLivemark.unregisterForUpdates(node, resultObserver);
-        aCallback(aLivemark);
-      }
-    }
-  };
-  aLivemark.registerForUpdates(node, resultObserver);
-  aLivemark.reload();
-}
-
-]]>
-</script>
-</window>
deleted file mode 100644
--- a/toolkit/components/places/tests/chrome/test_341972a.xul
+++ /dev/null
@@ -1,83 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet
-  href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
-<window title="Update Livemark SiteURI"
-  xmlns:html="http://www.w3.org/1999/xhtml"
-  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-  onload="runTest()">
-  <script type="application/javascript"
-   src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-
-  <body xmlns="http://www.w3.org/1999/xhtml" />
-
-<script type="application/javascript">
-<![CDATA[
-/*
- Test updating livemark siteURI to the value from the feed
- */
-SimpleTest.waitForExplicitFinish();
-
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
-ChromeUtils.import("resource://gre/modules/PlacesUtils.jsm");
-
-function runTest() {
-  const FEEDSPEC = "http://mochi.test:8888/tests/toolkit/components/places/tests/chrome/sample_feed.atom";
-  const INITIALSITESPEC = "http://mochi.test:8888/";
-  const FEEDSITESPEC = "http://example.org/"; 
-
-  PlacesUtils.livemarks.addLivemark(
-    { title: "foo"
-    , parentGuid: PlacesUtils.bookmarks.toolbarGuid
-    , feedURI: NetUtil.newURI(FEEDSPEC)
-    , siteURI: NetUtil.newURI(INITIALSITESPEC)
-    })
-    .then(function (aLivemark) {
-      is(aLivemark.siteURI.spec, INITIALSITESPEC,
-         "Has correct initial livemark site URI");
-
-      waitForLivemarkLoad(aLivemark, function (aLivemark) {
-        is(aLivemark.siteURI.spec, FEEDSITESPEC,
-           "livemark site URI set to value in feed");
-
-        PlacesUtils.livemarks.removeLivemark(aLivemark).then(() => {
-          SimpleTest.finish();
-        });
-      });
-    }, function () {
-      is(true, false, "Should not fail adding a livemark");
-    }
-  );
-}
-
-function waitForLivemarkLoad(aLivemark, aCallback) {
-  // Don't need a real node here.
-  let node = {};
-  let resultObserver = {
-    nodeInserted: function() {},
-    nodeRemoved: function() {},
-    nodeAnnotationChanged: function() {},
-    nodeTitleChanged: function() {},
-    nodeHistoryDetailsChanged: function() {},
-    nodeMoved: function() {},
-    ontainerStateChanged: function () {},
-    sortingChanged: function() {},
-    batching: function() {},
-    invalidateContainer: function(node) {
-      isnot(aLivemark.status, Ci.mozILivemark.STATUS_FAILED,
-            "Loading livemark should success");
-      if (aLivemark.status == Ci.mozILivemark.STATUS_READY) {
-        aLivemark.unregisterForUpdates(node, resultObserver);
-        aCallback(aLivemark);
-      }
-    }
-  };
-  aLivemark.registerForUpdates(node, resultObserver);
-  aLivemark.reload();
-}
-
-]]>
-</script>
-
-</window>
deleted file mode 100644
--- a/toolkit/components/places/tests/chrome/test_341972b.xul
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet
-  href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
-<window title="Update Livemark SiteURI, null to start"
-  xmlns:html="http://www.w3.org/1999/xhtml"
-  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-  onload="runTest()">
-  <script type="application/javascript"
-   src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-
-  <body xmlns="http://www.w3.org/1999/xhtml" />
-
-<script type="application/javascript">
-<![CDATA[
-/*
- Test updating livemark siteURI to the value from the feed, when it's null
- */
-SimpleTest.waitForExplicitFinish();
-
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
-ChromeUtils.import("resource://gre/modules/PlacesUtils.jsm");
-
-function runTest() {
-  const FEEDSPEC = "http://mochi.test:8888/tests/toolkit/components/places/tests/chrome/sample_feed.atom";
-  const FEEDSITESPEC = "http://example.org/"; 
-
-  PlacesUtils.livemarks.addLivemark(
-    { title: "foo"
-    , parentGuid: PlacesUtils.bookmarks.toolbarGuid
-    , feedURI: NetUtil.newURI(FEEDSPEC)
-    })
-    .then(function (aLivemark) {
-      is(aLivemark.siteURI, null, "Has null livemark site URI");
-
-      waitForLivemarkLoad(aLivemark, function (aLivemark) {
-        is(aLivemark.siteURI.spec, FEEDSITESPEC,
-           "livemark site URI set to value in feed");
-
-        PlacesUtils.livemarks.removeLivemark(aLivemark).then(() => {
-          SimpleTest.finish();
-        });
-      });
-    }, function () {
-      is(true, false, "Should not fail adding a livemark");
-    }
-  );
-}
-
-function waitForLivemarkLoad(aLivemark, aCallback) {
-  // Don't need a real node here.
-  let node = {};
-  let resultObserver = {
-    nodeInserted: function() {},
-    nodeRemoved: function() {},
-    nodeAnnotationChanged: function() {},
-    nodeTitleChanged: function() {},
-    nodeHistoryDetailsChanged: function() {},
-    nodeMoved: function() {},
-    ontainerStateChanged: function () {},
-    sortingChanged: function() {},
-    batching: function() {},
-    invalidateContainer: function(node) {
-      isnot(aLivemark.status, Ci.mozILivemark.STATUS_FAILED,
-            "Loading livemark should success");
-      if (aLivemark.status == Ci.mozILivemark.STATUS_READY) {
-        aLivemark.unregisterForUpdates(node, resultObserver);
-        aCallback(aLivemark);
-      }
-    }
-  };
-  aLivemark.registerForUpdates(node, resultObserver);
-  aLivemark.reload();
-}
-
-]]>
-</script>
-
-</window>
deleted file mode 100644
--- a/toolkit/components/places/tests/chrome/test_342484.xul
+++ /dev/null
@@ -1,84 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet
-  href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
-<window title="Add Bad Livemarks"
-  xmlns:html="http://www.w3.org/1999/xhtml"
-  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-  onload="runTest()">
-  <script type="application/javascript"
-   src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-
-  <body xmlns="http://www.w3.org/1999/xhtml" />
-
-<script type="application/javascript">
-<![CDATA[
-/*
- Test loading feeds with items that aren't allowed
- */
-SimpleTest.waitForExplicitFinish();
-
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
-ChromeUtils.import("resource://gre/modules/PlacesUtils.jsm");
-
-function runTest() {
-  const FEEDSPEC = "http://mochi.test:8888/tests/toolkit/components/places/tests/chrome/bad_links.atom";
-  const GOOD_URLS = ["http://example.org/first", "http://example.org/last"];
-
-  PlacesUtils.livemarks.addLivemark(
-    { title: "foo"
-    , parentGuid: PlacesUtils.bookmarks.toolbarGuid
-    , feedURI: NetUtil.newURI(FEEDSPEC)
-    , siteURI: NetUtil.newURI("http:/mochi.test/")
-    })
-    .then(function (aLivemark) {
-      waitForLivemarkLoad(aLivemark, function (aLivemark) {
-        let nodes = aLivemark.getNodesForContainer({});
-
-        is(nodes.length, 2, "Created the two good livemark items");
-        for (let i = 0; i < nodes.length; ++i) {
-          let node = nodes[i];
-          ok(GOOD_URLS.includes(node.uri), "livemark item created with bad uri " + node.uri);
-        }
-
-        PlacesUtils.livemarks.removeLivemark(aLivemark).then(() => {
-          SimpleTest.finish();
-        });
-      });
-    }, function () {
-      is(true, false, "Should not fail adding a livemark");
-    }
-  );
-}
-
-function waitForLivemarkLoad(aLivemark, aCallback) {
-  // Don't need a real node here.
-  let node = {};
-  let resultObserver = {
-    nodeInserted: function() {},
-    nodeRemoved: function() {},
-    nodeAnnotationChanged: function() {},
-    nodeTitleChanged: function() {},
-    nodeHistoryDetailsChanged: function() {},
-    nodeMoved: function() {},
-    ontainerStateChanged: function () {},
-    sortingChanged: function() {},
-    batching: function() {},
-    invalidateContainer: function(node) {
-      isnot(aLivemark.status, Ci.mozILivemark.STATUS_FAILED,
-            "Loading livemark should success");
-      if (aLivemark.status == Ci.mozILivemark.STATUS_READY) {
-        aLivemark.unregisterForUpdates(node, resultObserver);
-        aCallback(aLivemark);
-      }
-    }
-  };
-  aLivemark.registerForUpdates(node, resultObserver);
-  aLivemark.reload();
-}
-
-]]>
-</script>
-
-</window>
deleted file mode 100644
--- a/toolkit/components/places/tests/chrome/test_381357.xul
+++ /dev/null
@@ -1,81 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet
-  href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
-<window title="Add Livemarks from RSS feed served as text/html"
-  xmlns:html="http://www.w3.org/1999/xhtml"
-  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-  onload="runTest()">
-  <script type="application/javascript"
-   src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-
-  <body xmlns="http://www.w3.org/1999/xhtml" />
-
-<script type="application/javascript">
-<![CDATA[
-/*
- Test loading feeds with text/html 
- */
-SimpleTest.waitForExplicitFinish();
-
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
-ChromeUtils.import("resource://gre/modules/PlacesUtils.jsm");
-
-function runTest() {
-  const FEEDSPEC = "http://mochi.test:8888/tests/toolkit/components/places/tests/chrome/rss_as_html.rss";
-
-  PlacesUtils.livemarks.addLivemark(
-    { title: "foo"
-    , parentGuid: PlacesUtils.bookmarks.toolbarGuid
-    , feedURI: NetUtil.newURI(FEEDSPEC)
-    , siteURI: NetUtil.newURI("http:/mochi.test/")
-    })
-    .then(function (aLivemark) {
-      waitForLivemarkLoad(aLivemark, function (aLivemark) {
-        let nodes = aLivemark.getNodesForContainer({});
-
-        is(nodes[0].title, "The First Title",
-           "livemark site URI set to value in feed");
-
-        PlacesUtils.livemarks.removeLivemark(aLivemark).then(() => {
-          SimpleTest.finish();
-        });
-      });
-    }, function () {
-      is(true, false, "Should not fail adding a livemark");
-      SimpleTest.finish();
-    }
-  );
-}
-
-function waitForLivemarkLoad(aLivemark, aCallback) {
-  // Don't need a real node here.
-  let node = {};
-  let resultObserver = {
-    nodeInserted: function() {},
-    nodeRemoved: function() {},
-    nodeAnnotationChanged: function() {},
-    nodeTitleChanged: function() {},
-    nodeHistoryDetailsChanged: function() {},
-    nodeMoved: function() {},
-    ontainerStateChanged: function () {},
-    sortingChanged: function() {},
-    batching: function() {},
-    invalidateContainer: function(node) {
-      isnot(aLivemark.status, Ci.mozILivemark.STATUS_FAILED,
-            "Loading livemark should success");
-      if (aLivemark.status == Ci.mozILivemark.STATUS_READY) {
-        aLivemark.unregisterForUpdates(node, resultObserver);
-        aCallback(aLivemark);
-      }
-    }
-  };
-  aLivemark.registerForUpdates(node, resultObserver);
-  aLivemark.reload();
-}
-
-]]>
-</script>
-
-</window>
deleted file mode 100644
--- a/toolkit/components/places/tests/chrome/test_reloadLivemarks.xul
+++ /dev/null
@@ -1,151 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet
-  href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
-<window title="Reload Livemarks"
-  xmlns:html="http://www.w3.org/1999/xhtml"
-  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-  onload="runTest()" onunload="cleanup()">
-  <script type="application/javascript"
-   src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-
-  <body xmlns="http://www.w3.org/1999/xhtml" />
-
-<script type="application/javascript">
-<![CDATA[
-// Test that for concurrent reload of livemarks.
-
-SimpleTest.waitForExplicitFinish();
-
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
-ChromeUtils.import("resource://gre/modules/PlacesUtils.jsm");
-
-let gLivemarks = [
-  { id: -1,
-    title: "foo",
-    parentGuid: PlacesUtils.bookmarks.toolbarGuid,
-    feedURI: NetUtil.newURI("http://mochi.test:8888/tests/toolkit/components/places/tests/chrome/link-less-items.rss")
-  },
-  { id: -1,
-    title: "bar",
-    parentGuid: PlacesUtils.bookmarks.toolbarGuid,
-    feedURI: NetUtil.newURI("http://mochi.test:8888/tests/toolkit/components/places/tests/chrome/link-less-items-no-site-uri.rss")
-  },
-];
-
-function runTest()
-{
-  addLivemarks(function () {
-    reloadLivemarks(false, function () {
-      reloadLivemarks(true, function () {
-        removeLivemarks(SimpleTest.finish);
-      });
-    });
-    // Ensure this normal reload doesn't overwrite the forced one.
-    PlacesUtils.livemarks.reloadLivemarks();
-  });
-}
-
-function addLivemarks(aCallback) {
-  info("Adding livemarks");
-  let count = gLivemarks.length;
-  gLivemarks.forEach(function(aLivemarkData) {
-    PlacesUtils.livemarks.addLivemark(aLivemarkData)
-      .then(function (aLivemark) {
-        ok(aLivemark.feedURI.equals(aLivemarkData.feedURI), "Livemark added");
-        aLivemarkData.id = aLivemark.id;
-        if (--count == 0) {
-          aCallback();
-        }
-      },
-      function () {
-        is(true, false, "Should not fail adding a livemark.");
-        aCallback();
-      });
-  });
-}
-
-function reloadLivemarks(aForceUpdate, aCallback) {
-  info("Reloading livemarks with forceUpdate: " + aForceUpdate);
-  let count = gLivemarks.length;
-  gLivemarks.forEach(function(aLivemarkData) {
-    PlacesUtils.livemarks.getLivemark(aLivemarkData)
-      .then(aLivemark => {
-        ok(aLivemark.feedURI.equals(aLivemarkData.feedURI), "Livemark found");
-        aLivemarkData._observer = new resultObserver(aLivemark, function() {
-          if (++count == gLivemarks.length) {
-            aCallback();
-          }
-        });
-        if (--count == 0) {
-          PlacesUtils.livemarks.reloadLivemarks(aForceUpdate);
-        }
-      },
-      function() {
-        is(true, false, "Should not fail getting a livemark.");
-        aCallback();
-      }
-    );
-  });
-}
-
-function removeLivemarks(aCallback) {
-  info("Removing livemarks");
-  let count = gLivemarks.length;
-  gLivemarks.forEach(function(aLivemarkData) {
-    PlacesUtils.livemarks.removeLivemark(aLivemarkData).then(
-      function (aLivemark) {
-        if (--count == 0) {
-          aCallback();
-        }
-      },
-      function() {
-        is(true, false, "Should not fail adding a livemark.");
-        aCallback();
-      }
-    );
-  });
-}
-
-function resultObserver(aLivemark, aCallback) {
-  this._node = {};
-  this._livemark = aLivemark;
-  this._callback = aCallback;
-  this._livemark.registerForUpdates(this._node, this);
-}
-resultObserver.prototype = {
-  nodeInserted: function() {},
-  nodeRemoved: function() {},
-  nodeAnnotationChanged: function() {},
-  nodeTitleChanged: function() {},
-  nodeHistoryDetailsChanged: function() {},
-  nodeMoved: function() {},
-  ontainerStateChanged: function () {},
-  sortingChanged: function() {},
-  batching: function() {},
-  invalidateContainer: function(aContainer) {
-    // Wait for load finish.
-    if (this._livemark.status == Ci.mozILivemark.STATUS_LOADING)
-      return;
-
-    this._terminate();
-    this._callback();
-  },
-  _terminate: function () {
-    if (!this._terminated) {
-      this._livemark.unregisterForUpdates(this._node);
-      this._terminated = true;
-    }
-  }
-};
-
-function cleanup() {
-  gLivemarks.forEach(function(aLivemarkData) {
-    if (aLivemarkData._observer)
-      aLivemarkData._observer._terminate();
-  });
-}
-]]>
-</script>
-</window>
--- a/toolkit/components/places/tests/queries/head_queries.js
+++ b/toolkit/components/places/tests/queries/head_queries.js
@@ -122,25 +122,16 @@ async function task_populateDB(aArray) {
         await PlacesUtils.bookmarks.insert({
           parentGuid: qdata.parentGuid,
           type: PlacesUtils.bookmarks.TYPE_FOLDER,
           title: qdata.title,
           index: qdata.index,
         });
       }
 
-      if (qdata.isLivemark) {
-        await PlacesUtils.livemarks.addLivemark({ title: qdata.title,
-                                                  parentId: (await PlacesUtils.promiseItemId(qdata.parentGuid)),
-                                                  index: qdata.index,
-                                                  feedURI: uri(qdata.feedURI),
-                                                  siteURI: uri(qdata.uri),
-                                                });
-      }
-
       if (qdata.isBookmark) {
         let data = {
           parentGuid: qdata.parentGuid,
           index: qdata.index,
           title: qdata.title,
           url: qdata.uri,
         };
 
@@ -206,17 +197,16 @@ function queryData(obj) {
   this.removeAnnotation = !!obj.removeAnnotation;
   this.annoName = obj.annoName ? obj.annoName : "";
   this.annoVal = obj.annoVal ? obj.annoVal : "";
   this.isItemAnnotation = obj.isItemAnnotation ? obj.isItemAnnotation : false;
   this.itemId = obj.itemId ? obj.itemId : 0;
   this.annoMimeType = obj.annoMimeType ? obj.annoMimeType : "";
   this.isTag = obj.isTag ? obj.isTag : false;
   this.tagArray = obj.tagArray ? obj.tagArray : null;
-  this.isLivemark = obj.isLivemark ? obj.isLivemark : false;
   this.parentGuid = obj.parentGuid || PlacesUtils.bookmarks.unfiledGuid;
   this.feedURI = obj.feedURI ? obj.feedURI : "";
   this.index = obj.index ? obj.index : PlacesUtils.bookmarks.DEFAULT_INDEX;
   this.isFolder = obj.isFolder ? obj.isFolder : false;
   this.contractId = obj.contractId ? obj.contractId : "";
   this.lastModified = obj.lastModified ? obj.lastModified : null;
   this.dateAdded = obj.dateAdded ? obj.dateAdded : null;
   this.keyword = obj.keyword ? obj.keyword : "";
deleted file mode 100644
--- a/toolkit/components/places/tests/sync/livemark.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
-  <title>Livemark Feed</title>
-  <link href="https://example.com/"/>
-  <updated>2016-08-09T19:51:45.147Z</updated>
-  <author>
-    <name>John Doe</name>
-  </author>
-  <id>urn:uuid:e7947414-6ee0-4009-ae75-8b0ad3c6894b</id>
-  <entry>
-    <title>Some awesome article</title>
-    <link href="https://example.com/some-article"/>
-    <id>urn:uuid:d72ce019-0a56-4a0b-ac03-f66117d78141</id>
-    <updated>2016-08-09T19:57:22.178Z</updated>
-    <summary>My great article summary.</summary>
-  </entry>
-</feed>
--- a/toolkit/components/places/tests/sync/test_bookmark_kinds.js
+++ b/toolkit/components/places/tests/sync/test_bookmark_kinds.js
@@ -1,383 +1,11 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
-add_task(async function test_livemarks() {
-  let { site, stopServer } = makeLivemarkServer();
-
-  try {
-    let buf = await openMirror("livemarks");
-
-    let unfiledFolderId =
-      await PlacesUtils.promiseItemId(PlacesUtils.bookmarks.unfiledGuid);
-
-    info("Set up mirror");
-    await PlacesUtils.bookmarks.insertTree({
-      guid: PlacesUtils.bookmarks.menuGuid,
-      children: [{
-        guid: "livemarkAAAA",
-        type: PlacesUtils.bookmarks.TYPE_FOLDER,
-        title: "A",
-        annos: [{
-          name: PlacesUtils.LMANNO_FEEDURI,
-          value: site + "/feed/a",
-        }],
-      }],
-    });
-    await storeRecords(buf, shuffle([{
-      id: "menu",
-      type: "folder",
-      children: ["livemarkAAAA"],
-    }, {
-      id: "livemarkAAAA",
-      type: "livemark",
-      title: "A",
-      feedUri: site + "/feed/a",
-    }]), { needsMerge: false });
-    await PlacesTestUtils.markBookmarksAsSynced();
-
-    info("Make local changes");
-    await PlacesUtils.livemarks.addLivemark({
-      parentGuid: PlacesUtils.bookmarks.toolbarGuid,
-      guid: "livemarkBBBB",
-      title: "B",
-      feedURI: Services.io.newURI(site + "/feed/b-local"),
-      siteURI: Services.io.newURI(site + "/site/b-local"),
-    });
-    let livemarkD = await PlacesUtils.livemarks.addLivemark({
-      parentGuid: PlacesUtils.bookmarks.menuGuid,
-      guid: "livemarkDDDD",
-      title: "D",
-      feedURI: Services.io.newURI(site + "/feed/d"),
-      siteURI: Services.io.newURI(site + "/site/d"),
-    });
-
-    info("Make remote changes");
-    await storeRecords(buf, shuffle([{
-      id: "livemarkAAAA",
-      type: "livemark",
-      title: "A (remote)",
-      feedUri: site + "/feed/a-remote",
-    }, {
-      id: "toolbar",
-      type: "folder",
-      children: ["livemarkCCCC", "livemarkB111"],
-    }, {
-      id: "unfiled",
-      type: "folder",
-      children: ["livemarkEEEE"],
-    }, {
-      id: "livemarkCCCC",
-      type: "livemark",
-      title: "C (remote)",
-      feedUri: site + "/feed/c-remote",
-    }, {
-      id: "livemarkB111",
-      type: "livemark",
-      title: "B",
-      feedUri: site + "/feed/b-remote",
-    }, {
-      id: "livemarkEEEE",
-      type: "livemark",
-      title: "E",
-      feedUri: site + "/feed/e",
-      siteUri: site + "/site/e",
-    }]));
-
-    info("Apply remote");
-    let observer = expectBookmarkChangeNotifications();
-    let changesToUpload = await buf.apply();
-    deepEqual(await buf.fetchUnmergedGuids(), [], "Should merge all items");
-
-    let menuInfo = await PlacesUtils.bookmarks.fetch(
-      PlacesUtils.bookmarks.menuGuid);
-    let toolbarInfo = await PlacesUtils.bookmarks.fetch(
-      PlacesUtils.bookmarks.toolbarGuid);
-    deepEqual(changesToUpload, {
-      livemarkDDDD: {
-        tombstone: false,
-        counter: 1,
-        synced: false,
-        cleartext: {
-          id: "livemarkDDDD",
-          type: "livemark",
-          parentid: "menu",
-          hasDupe: true,
-          parentName: BookmarksMenuTitle,
-          dateAdded: PlacesUtils.toDate(livemarkD.dateAdded).getTime(),
-          title: "D",
-          feedUri: site + "/feed/d",
-          siteUri: site + "/site/d",
-        },
-      },
-      menu: {
-        tombstone: false,
-        counter: 2,
-        synced: false,
-        cleartext: {
-          id: "menu",
-          type: "folder",
-          parentid: "places",
-          hasDupe: true,
-          parentName: "",
-          dateAdded: menuInfo.dateAdded.getTime(),
-          title: menuInfo.title,
-          children: ["livemarkAAAA", "livemarkDDDD"],
-        },
-      },
-      toolbar: {
-        tombstone: false,
-        counter: 1,
-        synced: false,
-        cleartext: {
-          id: "toolbar",
-          type: "folder",
-          parentid: "places",
-          hasDupe: true,
-          parentName: "",
-          dateAdded: toolbarInfo.dateAdded.getTime(),
-          title: toolbarInfo.title,
-          children: ["livemarkCCCC", "livemarkB111"],
-        },
-      },
-    }, "Should upload new local livemark A");
-
-    await assertLocalTree(PlacesUtils.bookmarks.rootGuid, {
-      guid: PlacesUtils.bookmarks.rootGuid,
-      type: PlacesUtils.bookmarks.TYPE_FOLDER,
-      index: 0,
-      title: "",
-      children: [{
-        guid: PlacesUtils.bookmarks.menuGuid,
-        type: PlacesUtils.bookmarks.TYPE_FOLDER,
-        index: 0,
-        title: BookmarksMenuTitle,
-        children: [{
-          guid: "livemarkAAAA",
-          type: PlacesUtils.bookmarks.TYPE_FOLDER,
-          index: 0,
-          title: "A (remote)",
-          annos: [{
-            name: PlacesUtils.LMANNO_FEEDURI,
-            flags: 0,
-            expires: PlacesUtils.annotations.EXPIRE_NEVER,
-            value: site + "/feed/a-remote",
-          }],
-        }, {
-          guid: "livemarkDDDD",
-          type: PlacesUtils.bookmarks.TYPE_FOLDER,
-          index: 1,
-          title: "D",
-          annos: [{
-            name: PlacesUtils.LMANNO_FEEDURI,
-            flags: 0,
-            expires: PlacesUtils.annotations.EXPIRE_NEVER,
-            value: site + "/feed/d",
-          }, {
-            name: PlacesUtils.LMANNO_SITEURI,
-            flags: 0,
-            expires: PlacesUtils.annotations.EXPIRE_NEVER,
-            value: site + "/site/d",
-          }],
-        }],
-      }, {
-        guid: PlacesUtils.bookmarks.toolbarGuid,
-        type: PlacesUtils.bookmarks.TYPE_FOLDER,
-        index: 1,
-        title: BookmarksToolbarTitle,
-        children: [{
-          guid: "livemarkCCCC",
-          type: PlacesUtils.bookmarks.TYPE_FOLDER,
-          index: 0,
-          title: "C (remote)",
-          annos: [{
-            name: PlacesUtils.LMANNO_FEEDURI,
-            flags: 0,
-            expires: PlacesUtils.annotations.EXPIRE_NEVER,
-            value: site + "/feed/c-remote",
-          }],
-        }, {
-          guid: "livemarkB111",
-          type: PlacesUtils.bookmarks.TYPE_FOLDER,
-          index: 1,
-          title: "B",
-          annos: [{
-            name: PlacesUtils.LMANNO_FEEDURI,
-            flags: 0,
-            expires: PlacesUtils.annotations.EXPIRE_NEVER,
-            value: site + "/feed/b-remote",
-          }],
-        }],
-      }, {
-        guid: PlacesUtils.bookmarks.unfiledGuid,
-        type: PlacesUtils.bookmarks.TYPE_FOLDER,
-        index: 3,
-        title: UnfiledBookmarksTitle,
-        children: [{
-          guid: "livemarkEEEE",
-          type: PlacesUtils.bookmarks.TYPE_FOLDER,
-          index: 0,
-          title: "E",
-          annos: [{
-            name: PlacesUtils.LMANNO_FEEDURI,
-            flags: 0,
-            expires: PlacesUtils.annotations.EXPIRE_NEVER,
-            value: site + "/feed/e",
-          }, {
-            name: PlacesUtils.LMANNO_SITEURI,
-            flags: 0,
-            expires: PlacesUtils.annotations.EXPIRE_NEVER,
-            value: site + "/site/e",
-          }],
-        }],
-      }, {
-        guid: PlacesUtils.bookmarks.mobileGuid,
-        type: PlacesUtils.bookmarks.TYPE_FOLDER,
-        index: 4,
-        title: MobileBookmarksTitle,
-      }],
-    }, "Should apply and dedupe livemarks");
-
-    let livemarkA = await PlacesUtils.livemarks.getLivemark({
-      guid: "livemarkAAAA",
-    });
-    let livemarkB = await PlacesUtils.livemarks.getLivemark({
-      guid: "livemarkB111",
-    });
-    let livemarkC = await PlacesUtils.livemarks.getLivemark({
-      guid: "livemarkCCCC",
-    });
-    let livemarkE = await PlacesUtils.livemarks.getLivemark({
-      guid: "livemarkEEEE",
-    });
-
-    observer.check([{
-      name: "onItemChanged",
-      params: { itemId: livemarkB.id, property: "guid", isAnnoProperty: false,
-                newValue: "livemarkB111", parentId: PlacesUtils.toolbarFolderId,
-                type: PlacesUtils.bookmarks.TYPE_FOLDER, guid: "livemarkB111",
-                parentGuid: "toolbar_____", oldValue: "livemarkBBBB",
-                source: PlacesUtils.bookmarks.SOURCES.SYNC },
-    }, {
-      name: "bookmark-added",
-      params: { itemId: livemarkC.id, parentId: PlacesUtils.toolbarFolderId,
-                index: 0, type: PlacesUtils.bookmarks.TYPE_FOLDER,
-                urlHref: "", title: "C (remote)", guid: "livemarkCCCC",
-                parentGuid: PlacesUtils.bookmarks.toolbarGuid,
-                source: PlacesUtils.bookmarks.SOURCES.SYNC },
-    }, {
-      name: "bookmark-added",
-      params: { itemId: livemarkE.id,
-                parentId: unfiledFolderId,
-                index: 0, type: PlacesUtils.bookmarks.TYPE_FOLDER,
-                urlHref: "", title: "E", guid: "livemarkEEEE",
-                parentGuid: "unfiled_____",
-                source: PlacesUtils.bookmarks.SOURCES.SYNC },
-    }, {
-      name: "onItemMoved",
-      params: { itemId: livemarkB.id, oldParentId: PlacesUtils.toolbarFolderId,
-                oldIndex: 0, newParentId: PlacesUtils.toolbarFolderId,
-                newIndex: 1, type: PlacesUtils.bookmarks.TYPE_FOLDER,
-                guid: "livemarkB111", uri: null,
-                oldParentGuid: PlacesUtils.bookmarks.toolbarGuid,
-                newParentGuid: PlacesUtils.bookmarks.toolbarGuid,
-                source: PlacesUtils.bookmarks.SOURCES.SYNC },
-    }, {
-      name: "onItemChanged",
-      params: { itemId: livemarkA.id, property: "title", isAnnoProperty: false,
-                newValue: "A (remote)", type: PlacesUtils.bookmarks.TYPE_FOLDER,
-                parentId: PlacesUtils.bookmarksMenuFolderId,
-                guid: "livemarkAAAA",
-                parentGuid: PlacesUtils.bookmarks.menuGuid, oldValue: "A",
-                source: PlacesUtils.bookmarks.SOURCES.SYNC },
-    }, {
-      name: "onItemChanged",
-      params: { itemId: livemarkA.id, property: PlacesUtils.LMANNO_FEEDURI,
-                isAnnoProperty: true, newValue: "",
-                type: PlacesUtils.bookmarks.TYPE_FOLDER,
-                parentId: PlacesUtils.bookmarksMenuFolderId,
-                guid: "livemarkAAAA",
-                parentGuid: PlacesUtils.bookmarks.menuGuid, oldValue: "",
-                source: PlacesUtils.bookmarks.SOURCES.SYNC },
-    }, {
-      name: "onItemChanged",
-      params: { itemId: livemarkA.id, property: PlacesUtils.LMANNO_FEEDURI,
-                isAnnoProperty: true, newValue: "",
-                type: PlacesUtils.bookmarks.TYPE_FOLDER,
-                parentId: PlacesUtils.bookmarksMenuFolderId,
-                guid: "livemarkAAAA",
-                parentGuid: PlacesUtils.bookmarks.menuGuid, oldValue: "",
-                source: PlacesUtils.bookmarks.SOURCES.SYNC },
-    }, {
-      name: "onItemChanged",
-      params: { itemId: livemarkC.id, property: "livemark/feedURI",
-                isAnnoProperty: true, newValue: "",
-                type: PlacesUtils.bookmarks.TYPE_FOLDER,
-                parentId: PlacesUtils.toolbarFolderId, guid: "livemarkCCCC",
-                parentGuid: PlacesUtils.bookmarks.toolbarGuid, oldValue: "",
-                source: PlacesUtils.bookmarks.SOURCES.SYNC },
-    }, {
-      name: "onItemChanged",
-      params: { itemId: livemarkB.id, property: PlacesUtils.LMANNO_FEEDURI,
-                isAnnoProperty: true, newValue: "",
-                type: PlacesUtils.bookmarks.TYPE_FOLDER,
-                parentId: PlacesUtils.toolbarFolderId,
-                guid: "livemarkB111",
-                parentGuid: PlacesUtils.bookmarks.toolbarGuid, oldValue: "",
-                source: PlacesUtils.bookmarks.SOURCES.SYNC },
-    }, {
-      name: "onItemChanged",
-      params: { itemId: livemarkB.id, property: PlacesUtils.LMANNO_SITEURI,
-                isAnnoProperty: true, newValue: "",
-                type: PlacesUtils.bookmarks.TYPE_FOLDER,
-                parentId: PlacesUtils.toolbarFolderId,
-                guid: "livemarkB111",
-                parentGuid: PlacesUtils.bookmarks.toolbarGuid, oldValue: "",
-                source: PlacesUtils.bookmarks.SOURCES.SYNC },
-    }, {
-      name: "onItemChanged",
-      params: { itemId: livemarkB.id, property: PlacesUtils.LMANNO_FEEDURI,
-                isAnnoProperty: true, newValue: "",
-                type: PlacesUtils.bookmarks.TYPE_FOLDER,
-                parentId: PlacesUtils.toolbarFolderId,
-                guid: "livemarkB111",
-                parentGuid: PlacesUtils.bookmarks.toolbarGuid, oldValue: "",
-                source: PlacesUtils.bookmarks.SOURCES.SYNC },
-    }, {
-      name: "onItemChanged",
-      params: { itemId: livemarkE.id, property: PlacesUtils.LMANNO_FEEDURI,
-                isAnnoProperty: true, newValue: "",
-                type: PlacesUtils.bookmarks.TYPE_FOLDER,
-                parentId: unfiledFolderId,
-                guid: "livemarkEEEE",
-                parentGuid: PlacesUtils.bookmarks.unfiledGuid,
-                oldValue: "",
-                source: PlacesUtils.bookmarks.SOURCES.SYNC },
-    }, {
-      name: "onItemChanged",
-      params: { itemId: livemarkE.id, property: PlacesUtils.LMANNO_SITEURI,
-                isAnnoProperty: true, newValue: "",
-                type: PlacesUtils.bookmarks.TYPE_FOLDER,
-                parentId: unfiledFolderId,
-                guid: "livemarkEEEE",
-                parentGuid: PlacesUtils.bookmarks.unfiledGuid,
-                oldValue: "",
-                source: PlacesUtils.bookmarks.SOURCES.SYNC },
-    }]);
-
-    await buf.finalize();
-  } finally {
-    await stopServer();
-  }
-
-  await PlacesUtils.bookmarks.eraseEverything();
-  await PlacesSyncUtils.bookmarks.reset();
-});
-
 add_task(async function test_queries() {
   let buf = await openMirror("queries");
 
   info("Set up places");
 
   // create a tag and grab the local folder ID.
   let tag = await PlacesUtils.bookmarks.insert({
     type: PlacesUtils.bookmarks.TYPE_FOLDER,
@@ -531,71 +159,25 @@ add_task(async function test_mismatched_
   }]);
 
   info("Apply remote");
   let changesToUpload = await buf.apply();
   deepEqual(await buf.fetchUnmergedGuids(), [], "Should merge all items");
 
   let idsToUpload = inspectChangeRecords(changesToUpload);
   deepEqual(idsToUpload, {
-    updated: [],
-    deleted: [],
-  }, "Should not reupload merged livemark");
+    updated: ["menu", "unfiled"],
+    deleted: ["l1nZZXfB8nC7"],
+  }, "Legacy livemark should be deleted remotely");
 
   await buf.finalize();
   await PlacesUtils.bookmarks.eraseEverything();
   await PlacesSyncUtils.bookmarks.reset();
 });
 
-add_task(async function test_mismatched_but_incompatible_folder_types() {
-  let sawMismatchError = false;
-  let recordTelemetryEvent = (object, method, value, extra) => {
-    // expecting to see an error for kind mismatches.
-    if (method == "apply" && value == "error" &&
-        extra && extra.why == "Can't merge different item kinds") {
-      sawMismatchError = true;
-    }
-  };
-  let buf = await openMirror("mismatched_incompatible_types",
-                             {recordTelemetryEvent});
-  try {
-    info("Set up mirror");
-    await PlacesUtils.bookmarks.insertTree({
-      guid: PlacesUtils.bookmarks.menuGuid,
-      children: [{
-        guid: "livemarkAAAA",
-        type: PlacesUtils.bookmarks.TYPE_FOLDER,
-        title: "LiveMark",
-        annos: [{
-          name: PlacesUtils.LMANNO_FEEDURI,
-          value: "http://example.com/feed/a",
-        }],
-      }],
-    });
-    await PlacesTestUtils.markBookmarksAsSynced();
-
-    info("Make remote changes");
-    await storeRecords(buf, [{
-      "id": "livemarkAAAA",
-      "type": "folder",
-      "title": "not really a Livemark",
-      "description": null,
-      "parentid": "menu",
-    }]);
-
-    info("Apply remote, should fail");
-    await Assert.rejects(buf.apply(), /Can't merge different item kinds/);
-    Assert.ok(sawMismatchError, "saw the correct mismatch event");
-  } finally {
-    await buf.finalize();
-    await PlacesUtils.bookmarks.eraseEverything();
-    await PlacesSyncUtils.bookmarks.reset();
-  }
-});
-
 add_task(async function test_different_but_compatible_bookmark_types() {
   try {
     let buf = await openMirror("partial_queries");
 
     await PlacesUtils.bookmarks.insertTree({
       guid: PlacesUtils.bookmarks.menuGuid,
       children: [
         {
--- a/toolkit/components/places/tests/sync/test_sync_utils.js
+++ b/toolkit/components/places/tests/sync/test_sync_utils.js
@@ -4,34 +4,16 @@ ChromeUtils.import("resource://testing-c
 ChromeUtils.defineModuleGetter(this, "Preferences",
                                "resource://gre/modules/Preferences.jsm");
 Cu.importGlobalProperties(["URLSearchParams"]);
 
 const SYNC_PARENT_ANNO = "sync/parent";
 
 var makeGuid = PlacesUtils.history.makeGuid;
 
-function makeLivemarkServer() {
-  let server = new HttpServer();
-  server.registerPrefixHandler("/feed/", do_get_file("./livemark.xml"));
-  server.start(-1);
-  return {
-    server,
-    get site() {
-      let { identity } = server;
-      let host = identity.primaryHost.includes(":") ?
-        `[${identity.primaryHost}]` : identity.primaryHost;
-      return `${identity.primaryScheme}://${host}:${identity.primaryPort}`;
-    },
-    stopServer() {
-      return new Promise(resolve => server.stop(resolve));
-    },
-  };
-}
-
 function shuffle(array) {
   let results = [];
   for (let i = 0; i < array.length; ++i) {
     let randomIndex = Math.floor(Math.random() * (i + 1));
     results[i] = results[randomIndex];
     results[randomIndex] = array[i];
   }
   return results;
@@ -1047,256 +1029,16 @@ add_task(async function test_insert() {
     equal(type, PlacesUtils.bookmarks.TYPE_SEPARATOR,
       "Separator should have correct type");
   }
 
   await PlacesUtils.bookmarks.eraseEverything();
   await PlacesSyncUtils.bookmarks.reset();
 });
 
-add_task(async function test_insert_livemark() {
-  let { site, stopServer } = makeLivemarkServer();
-
-  try {
-    info("Insert livemark with feed URL");
-    {
-      let livemark = await PlacesSyncUtils.bookmarks.insert({
-        kind: "livemark",
-        recordId: makeGuid(),
-        feed: site + "/feed/1",
-        parentRecordId: "menu",
-      });
-      let bmk = await PlacesUtils.bookmarks.fetch({
-        guid: await PlacesSyncUtils.bookmarks.recordIdToGuid(livemark.recordId),
-      });
-      equal(bmk.type, PlacesUtils.bookmarks.TYPE_FOLDER,
-        "Livemarks should be stored as folders");
-    }
-
-    let livemarkRecordId;
-    info("Insert livemark with site and feed URLs");
-    {
-      let livemark = await PlacesSyncUtils.bookmarks.insert({
-        kind: "livemark",
-        recordId: makeGuid(),
-        site,
-        feed: site + "/feed/1",
-        parentRecordId: "menu",
-      });
-      livemarkRecordId = livemark.recordId;
-    }
-
-    info("Try inserting livemark into livemark");
-    {
-      let livemark = await PlacesSyncUtils.bookmarks.insert({
-        kind: "livemark",
-        recordId: makeGuid(),
-        site,
-        feed: site + "/feed/1",
-        parentRecordId: livemarkRecordId,
-      });
-      ok(!livemark, "Should not insert livemark as child of livemark");
-    }
-  } finally {
-    await stopServer();
-  }
-
-  await PlacesUtils.bookmarks.eraseEverything();
-  await PlacesSyncUtils.bookmarks.reset();
-});
-
-add_task(async function test_update_livemark() {
-  let { site, stopServer } = makeLivemarkServer();
-  let feedURI = uri(site + "/feed/1");
-
-  try {
-    // We shouldn't reinsert the livemark if the URLs are the same.
-    info("Update livemark with same URLs");
-    {
-      let livemark = await PlacesUtils.livemarks.addLivemark({
-        parentGuid: PlacesUtils.bookmarks.menuGuid,
-        feedURI,
-        siteURI: uri(site),
-        index: PlacesUtils.bookmarks.DEFAULT_INDEX,
-      });
-
-      await PlacesSyncUtils.bookmarks.update({
-        recordId: livemark.guid,
-        feed: feedURI,
-      });
-      // `nsLivemarkService` returns references to `Livemark` instances, so we
-      // can compare them with `==` to make sure they haven't been replaced.
-      equal(await PlacesUtils.livemarks.getLivemark({
-        guid: livemark.guid,
-      }), livemark, "Livemark with same feed URL should not be replaced");
-
-      await PlacesSyncUtils.bookmarks.update({
-        recordId: livemark.guid,
-        site,
-      });
-      equal(await PlacesUtils.livemarks.getLivemark({
-        guid: livemark.guid,
-      }), livemark, "Livemark with same site URL should not be replaced");
-
-      await PlacesSyncUtils.bookmarks.update({
-        recordId: livemark.guid,
-        feed: feedURI,
-        site,
-      });
-      equal(await PlacesUtils.livemarks.getLivemark({
-        guid: livemark.guid,
-      }), livemark, "Livemark with same feed and site URLs should not be replaced");
-    }
-
-    info("Change livemark feed URL");
-    {
-      let livemark = await PlacesUtils.livemarks.addLivemark({
-        parentGuid: PlacesUtils.bookmarks.menuGuid,
-        feedURI,
-        index: PlacesUtils.bookmarks.DEFAULT_INDEX,
-      });
-
-      // Since we're reinserting, we need to pass all properties required
-      // for a new livemark. `update` won't merge the old and new ones.
-      await Assert.rejects(PlacesSyncUtils.bookmarks.update({
-        recordId: livemark.guid,
-        feed: site + "/feed/2",
-      }), /reinsert: Invalid value for property 'feed'/,
-          "Reinserting livemark with changed feed URL requires full record");
-
-      let newLivemark = await PlacesSyncUtils.bookmarks.update({
-        kind: "livemark",
-        parentRecordId: "menu",
-        recordId: livemark.guid,
-        feed: site + "/feed/2",
-      });
-      equal(newLivemark.recordId, livemark.guid,
-        "IDs should match for reinserted livemark with changed feed URL");
-      equal(newLivemark.feed.href, site + "/feed/2",
-        "Reinserted livemark should have changed feed URI");
-    }
-
-    info("Add livemark site URL");
-    {
-      let livemark = await PlacesUtils.livemarks.addLivemark({
-        parentGuid: PlacesUtils.bookmarks.menuGuid,
-        feedURI,
-      });
-      ok(livemark.feedURI.equals(feedURI), "Livemark feed URI should match");
-      ok(!livemark.siteURI, "Livemark should not have site URI");
-
-      await Assert.rejects(PlacesSyncUtils.bookmarks.update({
-        recordId: livemark.guid,
-        site,
-      }), /reinsert: Invalid value for property 'site'/,
-          "Reinserting livemark with new site URL requires full record");
-
-      let newLivemark = await PlacesSyncUtils.bookmarks.update({
-        kind: "livemark",
-        parentRecordId: "menu",
-        recordId: livemark.guid,
-        feed: feedURI,
-        site,
-      });
-      notEqual(newLivemark, livemark,
-        "Livemark with new site URL should replace old livemark");
-      equal(newLivemark.recordId, livemark.guid,
-        "IDs should match for reinserted livemark with new site URL");
-      equal(newLivemark.site.href, site + "/",
-        "Reinserted livemark should have new site URI");
-      equal(newLivemark.feed.href, feedURI.spec,
-        "Reinserted livemark with new site URL should have same feed URI");
-    }
-
-    info("Remove livemark site URL");
-    {
-      let livemark = await PlacesUtils.livemarks.addLivemark({
-        parentGuid: PlacesUtils.bookmarks.menuGuid,
-        feedURI,
-        siteURI: uri(site),
-        index: PlacesUtils.bookmarks.DEFAULT_INDEX,
-      });
-
-      await Assert.rejects(PlacesSyncUtils.bookmarks.update({
-        recordId: livemark.guid,
-        site: null,
-      }), /reinsert: Invalid value for property 'site'/,
-          "Reinserting livemark witout site URL requires full record");
-
-      let newLivemark = await PlacesSyncUtils.bookmarks.update({
-        kind: "livemark",
-        parentRecordId: "menu",
-        recordId: livemark.guid,
-        feed: feedURI,
-        site: null,
-      });
-      notEqual(newLivemark, livemark,
-        "Livemark without site URL should replace old livemark");
-      equal(newLivemark.recordId, livemark.guid,
-        "IDs should match for reinserted livemark without site URL");
-      ok(!newLivemark.site, "Reinserted livemark should not have site URI");
-    }
-
-    info("Change livemark site URL");
-    {
-      let livemark = await PlacesUtils.livemarks.addLivemark({
-        parentGuid: PlacesUtils.bookmarks.menuGuid,
-        feedURI,
-        siteURI: uri(site),
-        index: PlacesUtils.bookmarks.DEFAULT_INDEX,
-      });
-
-      await Assert.rejects(PlacesSyncUtils.bookmarks.update({
-        recordId: livemark.guid,
-        site: site + "/new",
-      }), /reinsert: Invalid value for property 'site'/,
-          "Reinserting livemark with changed site URL requires full record");
-
-      let newLivemark = await PlacesSyncUtils.bookmarks.update({
-        kind: "livemark",
-        parentRecordId: "menu",
-        recordId: livemark.guid,
-        feed: feedURI,
-        site: site + "/new",
-      });
-      notEqual(newLivemark, livemark,
-        "Livemark with changed site URL should replace old livemark");
-      equal(newLivemark.recordId, livemark.guid,
-        "IDs should match for reinserted livemark with changed site URL");
-      equal(newLivemark.site.href, site + "/new",
-        "Reinserted livemark should have changed site URI");
-    }
-
-    // Livemarks are stored as folders, but have different kinds. We should
-    // remove the folder and insert a livemark with the same GUID instead of
-    // trying to update the folder in-place.
-    info("Replace folder with livemark");
-    {
-      let folder = await PlacesUtils.bookmarks.insert({
-        type: PlacesUtils.bookmarks.TYPE_FOLDER,
-        parentGuid: PlacesUtils.bookmarks.menuGuid,
-        title: "Plain folder",
-      });
-      let livemark = await PlacesSyncUtils.bookmarks.update({
-        kind: "livemark",
-        parentRecordId: "menu",
-        recordId: folder.guid,
-        feed: feedURI,
-      });
-      equal(livemark.guid, folder.recordId,
-        "Livemark should have same GUID as replaced folder");
-    }
-  } finally {
-    await stopServer();
-  }
-
-  await PlacesUtils.bookmarks.eraseEverything();
-  await PlacesSyncUtils.bookmarks.reset();
-});
-
 add_task(async function test_insert_tags() {
   await Promise.all([{
     kind: "bookmark",
     url: "https://example.com",
     recordId: makeGuid(),
     parentRecordId: "menu",
     tags: ["foo", "bar"],
   }, {
@@ -1769,44 +1511,16 @@ add_task(async function test_fetch() {
     equal(item.url.href, `place:tag=taggy`, "Should not rewrite outgoing tag queries");
     equal(item.folder, "taggy", "Should return tag name for tag queries");
   }
 
   await PlacesUtils.bookmarks.eraseEverything();
   await PlacesSyncUtils.bookmarks.reset();
 });
 
-add_task(async function test_fetch_livemark() {
-  let { site, stopServer } = makeLivemarkServer();
-
-  try {
-    info("Create livemark");
-    let livemark = await PlacesUtils.livemarks.addLivemark({
-      parentGuid: PlacesUtils.bookmarks.menuGuid,
-      feedURI: uri(site + "/feed/1"),
-      siteURI: uri(site),
-      index: PlacesUtils.bookmarks.DEFAULT_INDEX,
-    });
-
-    info("Fetch livemark");
-    let item = await PlacesSyncUtils.bookmarks.fetch(livemark.guid);
-    deepEqual(Object.keys(item).sort(), ["recordId", "kind", "parentRecordId",
-      "feed", "site", "parentTitle", "title", "dateAdded"].sort(),
-      "Should include livemark-specific properties");
-    equal(item.feed.href, site + "/feed/1", "Should return feed URL");
-    equal(item.site.href, site + "/", "Should return site URL");
-    strictEqual(item.title, "", "Should include livemark title even if empty");
-  } finally {
-    await stopServer();
-  }
-
-  await PlacesUtils.bookmarks.eraseEverything();
-  await PlacesSyncUtils.bookmarks.reset();
-});
-
 add_task(async function test_pullChanges_new_parent() {
   await ignoreChangedRoots();
 
   let { syncedGuids, unsyncedFolder } = await moveSyncedBookmarksToUnsyncedParent();
 
   info("Unsynced parent and synced items should be tracked");
   let changes = await PlacesSyncUtils.bookmarks.pullChanges();
   deepEqual(Object.keys(changes).sort(),
@@ -2307,36 +2021,16 @@ add_task(async function test_touch() {
     deepEqual(Object.keys(changes).sort(), [bmk.recordId, "menu"].sort(),
       "Should return change records for revived bookmark and parent");
     equal(changes[bmk.recordId].counter, 1,
       "Change counter for revived bookmark should be 1");
 
     await setChangesSynced(changes);
   }
 
-  // Livemarks are stored as folders, but their kinds are different, so we
-  // should still bump their change counters.
-  let { site, stopServer } = makeLivemarkServer();
-  try {
-    let livemark = await PlacesSyncUtils.bookmarks.insert({
-      kind: "livemark",
-      recordId: makeGuid(),
-      feed: site + "/feed/1",
-      parentRecordId: "unfiled",
-    });
-
-    let changes = await PlacesSyncUtils.bookmarks.touch(livemark.recordId);
-    deepEqual(Object.keys(changes).sort(), [livemark.recordId, "unfiled"].sort(),
-      "Should return change records for revived livemark and parent");
-    equal(changes[livemark.recordId].counter, 1,
-      "Change counter for revived livemark should be 1");
-  } finally {
-    await stopServer();
-  }
-
   await PlacesUtils.bookmarks.eraseEverything();
   await PlacesSyncUtils.bookmarks.reset();
 });
 
 add_task(async function test_separator() {
   await ignoreChangedRoots();
 
   await PlacesSyncUtils.bookmarks.insert({
--- a/toolkit/components/places/tests/sync/xpcshell.ini
+++ b/toolkit/components/places/tests/sync/xpcshell.ini
@@ -1,12 +1,11 @@
 [DEFAULT]
 head = head_sync.js
 support-files =
-  livemark.xml
   sync_utils_bookmarks.html
   sync_utils_bookmarks.json
   mirror_corrupt.sqlite
   mirror_v1.sqlite
 
 [test_bookmark_corruption.js]
 [test_bookmark_deduping.js]
 [test_bookmark_deletion.js]
deleted file mode 100644
--- a/toolkit/components/places/tests/unit/livemark.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
-  <title>Livemark Feed</title>
-  <link href="https://example.com/"/>
-  <updated>2016-08-09T19:51:45.147Z</updated>
-  <author>
-    <name>John Doe</name>
-  </author>
-  <id>urn:uuid:e7947414-6ee0-4009-ae75-8b0ad3c6894b</id>
-  <entry>
-    <title>Some awesome article</title>
-    <link href="https://example.com/some-article"/>
-    <id>urn:uuid:d72ce019-0a56-4a0b-ac03-f66117d78141</id>
-    <updated>2016-08-09T19:57:22.178Z</updated>
-    <summary>My great article summary.</summary>
-  </entry>
-</feed>
--- a/toolkit/components/places/tests/unit/test_384370.js
+++ b/toolkit/components/places/tests/unit/test_384370.js
@@ -110,41 +110,33 @@ async function testMenuBookmarks() {
 
   folderNode.containerOpen = false;
   root.containerOpen = false;
 }
 
 async function testToolbarBookmarks() {
   let root = PlacesUtils.getFolderContents(PlacesUtils.bookmarks.toolbarGuid).root;
 
-  // child count (add 3 for pre-existing items)
-  Assert.equal(root.childCount, bookmarkData.length + 3);
+  // child count (add 2 for pre-existing items, one of the feeds is skipped
+  // because it doesn't have href)
+  Assert.equal(root.childCount, bookmarkData.length + 2);
 
-  let livemarkNode = root.getChild(1);
-  Assert.equal("Latest Headlines", livemarkNode.title);
-
-  let livemark = await PlacesUtils.livemarks.getLivemark({ id: livemarkNode.itemId });
+  // Livemarks are no more supported but may still exist in old html files.
+  let legacyLivemarkNode = root.getChild(1);
+  Assert.equal("Latest Headlines", legacyLivemarkNode.title);
   Assert.equal("http://en-us.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/",
-               livemark.siteURI.spec);
-  Assert.equal("http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml",
-               livemark.feedURI.spec);
-
-  livemarkNode = root.getChild(2);
-  Assert.equal("Latest Headlines No Site", livemarkNode.title);
-
-  livemark = await PlacesUtils.livemarks.getLivemark({ id: livemarkNode.itemId });
-  Assert.equal(null, livemark.siteURI);
-  Assert.equal("http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml",
-               livemark.feedURI.spec);
+               legacyLivemarkNode.uri);
+  Assert.equal(legacyLivemarkNode.type,
+               Ci.nsINavHistoryResultNode.RESULT_TYPE_URI);
 
   // test added bookmark data
-  let bookmarkNode = root.getChild(3);
+  let bookmarkNode = root.getChild(2);
   Assert.equal(bookmarkNode.uri, bookmarkData[0].uri.spec);
   Assert.equal(bookmarkNode.title, bookmarkData[0].title);
-  bookmarkNode = root.getChild(4);
+  bookmarkNode = root.getChild(3);
   Assert.equal(bookmarkNode.uri, bookmarkData[1].uri.spec);
   Assert.equal(bookmarkNode.title, bookmarkData[1].title);
 
   root.containerOpen = false;
 }
 
 function testUnfiledBookmarks() {
   let root = PlacesUtils.getFolderContents(PlacesUtils.bookmarks.unfiledGuid).root;
--- a/toolkit/components/places/tests/unit/test_async_transactions.js
+++ b/toolkit/components/places/tests/unit/test_async_transactions.js
@@ -282,26 +282,16 @@ function createTestFolderInfo(title = "T
                               children = undefined) {
   let info = { parentGuid, title };
   if (children) {
     info.children = children;
   }
   return info;
 }
 
-function isLivemarkTree(aTree) {
-  return !!aTree.annos &&
-         aTree.annos.some( a => a.name == PlacesUtils.LMANNO_FEEDURI );
-}
-
-async function ensureLivemarkCreatedByAddLivemark(aLivemarkGuid) {
-  // This throws otherwise.
-  await PlacesUtils.livemarks.getLivemark({ guid: aLivemarkGuid });
-}
-
 function removeAllDatesInTree(tree) {
   if ("lastModified" in tree) {
     delete tree.lastModified;
   }
   if ("dateAdded" in tree) {
     delete tree.dateAdded;
   }
 
@@ -329,18 +319,16 @@ async function ensureEqualBookmarksTrees
     if (aIgnoreAllDates) {
       removeAllDatesInTree(aOriginal);
       removeAllDatesInTree(aNew);
     } else if (!aOriginal.lastModified) {
       // Ignore lastModified for newly created items, for performance reasons.
       aNew.lastModified = aOriginal.lastModified;
     }
     Assert.deepEqual(aOriginal, aNew);
-    if (isLivemarkTree(aNew))
-      await ensureLivemarkCreatedByAddLivemark(aNew.guid);
     return;
   }
 
   for (let property of Object.keys(aOriginal)) {
     if (property == "children") {
       Assert.equal(aOriginal.children.length, aNew.children.length);
       for (let i = 0; i < aOriginal.children.length; i++) {
         await ensureEqualBookmarksTrees(aOriginal.children[i],
@@ -361,19 +349,16 @@ async function ensureEqualBookmarksTrees
         Assert.ok(!aNew.lastModified);
       else
         Assert.ok(is_time_ordered(aOriginal.lastModified, aNew.lastModified));
     } else if (aCheckParentAndPosition ||
              (property != "parentGuid" && property != "index")) {
       Assert.deepEqual(aOriginal[property], aNew[property]);
     }
   }
-
-  if (isLivemarkTree(aNew))
-    await ensureLivemarkCreatedByAddLivemark(aNew.guid);
 }
 
 async function ensureBookmarksTreeRestoredCorrectly(...aOriginalBookmarksTrees) {
   for (let originalTree of aOriginalBookmarksTrees) {
     let restoredTree =
       await PlacesUtils.promiseBookmarksTree(originalTree.guid);
     await ensureEqualBookmarksTrees(originalTree, restoredTree);
   }
@@ -1110,60 +1095,16 @@ add_task(async function test_creating_an
   observer.reset();
   await PT.undo();
   ensureUndoState(undoEntries, 1);
   ensureItemsRemoved(folder_info, separator_info);
   await PT.clearTransactionsHistory();
   ensureUndoState();
 });
 
-add_task(async function test_add_and_remove_livemark() {
-  let createLivemarkTxn = PT.NewLivemark(
-    { feedUrl: "http://test.remove.livemark",
-      parentGuid: PlacesUtils.bookmarks.unfiledGuid,
-      title: "Test Remove Livemark" });
-  let guid = await createLivemarkTxn.transact();
-  let originalInfo = await PlacesUtils.promiseBookmarksTree(guid);
-  Assert.ok(originalInfo);
-  await ensureLivemarkCreatedByAddLivemark(guid);
-
-  let removeTxn = PT.Remove(guid);
-  await removeTxn.transact();
-  await ensureNonExistent(guid);
-
-  async function undo() {
-    ensureUndoState([[removeTxn], [createLivemarkTxn]], 0);
-    await PT.undo();
-    ensureUndoState([[removeTxn], [createLivemarkTxn]], 1);
-    await ensureBookmarksTreeRestoredCorrectly(originalInfo);
-    await PT.undo();
-    ensureUndoState([[removeTxn], [createLivemarkTxn]], 2);
-    await ensureNonExistent(guid);
-  }
-  async function redo() {
-    ensureUndoState([[removeTxn], [createLivemarkTxn]], 2);
-    await PT.redo();
-    ensureUndoState([[removeTxn], [createLivemarkTxn]], 1);
-    await ensureBookmarksTreeRestoredCorrectly(originalInfo);
-    await PT.redo();
-    ensureUndoState([[removeTxn], [createLivemarkTxn]], 0);
-    await ensureNonExistent(guid);
-  }
-
-  await undo();
-  await redo();
-  await undo();
-  await redo();
-
-  // Cleanup
-  await undo();
-  observer.reset();
-  await PT.clearTransactionsHistory();
-});
-
 add_task(async function test_edit_title() {
   let bm_info = {
     parentGuid: PlacesUtils.bookmarks.unfiledGuid,
     url: "http://test_create_item.com",
     title: "Original Title",
   };
 
   function ensureTitleChange(aCurrentTitle) {
@@ -1599,65 +1540,16 @@ add_task(async function test_sort_folder
   // Cleanup
   observer.reset();
   await PT.undo();
   ensureOrder(originalOrder);
   await PT.undo();
   ensureItemsRemoved(...originalOrder, folder_info);
 });
 
-add_task(async function test_livemark_txns() {
-  let livemark_info =
-    { feedUrl: "http://test.feed.uri/",
-      parentGuid: PlacesUtils.bookmarks.unfiledGuid,
-      title: "Test Livemark" };
-  function ensureLivemarkAdded() {
-    ensureItemsAdded({ guid:       livemark_info.guid,
-                       title:      livemark_info.title,
-                       parentGuid: livemark_info.parentGuid,
-                       itemType:   PlacesUtils.bookmarks.TYPE_FOLDER });
-    let annos = [{ name:  PlacesUtils.LMANNO_FEEDURI,
-                   value: livemark_info.feedUrl }];
-    if ("siteUrl" in livemark_info) {
-      annos.push({ name: PlacesUtils.LMANNO_SITEURI,
-                   value: livemark_info.siteUrl });
-    }
-    ensureAnnotationsSet(livemark_info.guid, annos);
-  }
-  function ensureLivemarkRemoved() {
-    ensureItemsRemoved({ guid:       livemark_info.guid,
-                         parentGuid: livemark_info.parentGuid });
-  }
-
-  async function _testDoUndoRedoUndo() {
-    observer.reset();
-    livemark_info.guid = await PT.NewLivemark(livemark_info).transact();
-    ensureLivemarkAdded();
-
-    observer.reset();
-    await PT.undo();
-    ensureLivemarkRemoved();
-
-    observer.reset();
-    await PT.redo();
-    ensureLivemarkAdded();
-
-    await PT.undo();
-    ensureLivemarkRemoved();
-  }
-
-  await _testDoUndoRedoUndo();
-  livemark_info.siteUrl = "http://feed.site.uri/";
-  await _testDoUndoRedoUndo();
-
-  // Cleanup
-  observer.reset();
-  await PT.clearTransactionsHistory();
-});
-
 add_task(async function test_copy() {
   async function duplicate_and_test(aOriginalGuid) {
     let txn = PT.Copy({
       guid: aOriginalGuid, newParentGuid: PlacesUtils.bookmarks.unfiledGuid,
     });
     let duplicateGuid = await txn.transact();
     let originalInfo = await PlacesUtils.promiseBookmarksTree(aOriginalGuid);
     let duplicateInfo = await PlacesUtils.promiseBookmarksTree(duplicateGuid);
@@ -1697,22 +1589,19 @@ add_task(async function test_copy() {
   // Test duplicating leafs (bookmark, separator, empty folder)
   PT.NewBookmark({ url: "http://test.item.duplicate",
                    parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                    annos: [{ name: "Anno", value: "AnnoValue"}] });
   let sepTxn = PT.NewSeparator({
     parentGuid: PlacesUtils.bookmarks.unfiledGuid,
     index: 1,
   });
-  let livemarkTxn = PT.NewLivemark(
-    { feedUrl: "http://test.feed.uri",
-      parentGuid: PlacesUtils.bookmarks.unfiledGuid,
-      title: "Test Livemark", index: 1 });
+
   let emptyFolderTxn = PT.NewFolder(createTestFolderInfo());
-  for (let txn of [livemarkTxn, sepTxn, emptyFolderTxn]) {
+  for (let txn of [sepTxn, emptyFolderTxn]) {
     let guid = await txn.transact();
     await duplicate_and_test(guid);
   }
 
   // Test duplicating a folder having some contents.
   let filledFolderGuid = await PT.batch(async function() {
     let folderGuid = await PT.NewFolder(createTestFolderInfo()).transact();
     let nestedFolderGuid =
--- a/toolkit/components/places/tests/unit/test_bookmarks_html.js
+++ b/toolkit/components/places/tests/unit/test_bookmarks_html.js
@@ -49,18 +49,20 @@ var test_bookmarks = {
     { title: "Getting Started",
       url: "http://en-us.www.mozilla.com/en-US/firefox/central/",
       icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==",
     },
     { title: "Latest Headlines",
       url: "http://en-us.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/",
       feedUrl: "http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml",
     },
+    // This will be ignored, because it has no url.
     { title: "Latest Headlines No Site",
       feedUrl: "http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml",
+      ignore: true,
     },
   ],
   unfiled: [
     { title: "Example.tld",
       url: "http://example.tld/",
     },
   ],
 };
@@ -255,30 +257,28 @@ add_task(async function test_import_onto
 });
 
 async function testImportedBookmarks() {
   for (let group in test_bookmarks) {
     info("[testImportedBookmarks()] Checking group '" + group + "'");
 
     let root = PlacesUtils.getFolderContents(PlacesUtils.bookmarks[`${group}Guid`]).root;
 
-    let items = test_bookmarks[group];
+    let items = test_bookmarks[group].filter(b => !b.ignore);
     Assert.equal(root.childCount, items.length);
 
     for (let key in items) {
       await checkItem(items[key], root.getChild(key));
     }
 
     root.containerOpen = false;
   }
 }
 
 function checkItem(aExpected, aNode) {
-  let id = aNode.itemId;
-
   return (async function() {
     let bookmark = await PlacesUtils.bookmarks.fetch(aNode.bookmarkGuid);
 
     for (let prop in aExpected) {
       switch (prop) {
         case "type":
           Assert.equal(aNode.type, aExpected.type);
           break;
@@ -289,18 +289,17 @@ function checkItem(aExpected, aNode) {
           Assert.equal(PlacesUtils.toPRTime(bookmark.dateAdded),
                        aExpected.dateAdded);
           break;
         case "lastModified":
           Assert.equal(PlacesUtils.toPRTime(bookmark.lastModified),
                        aExpected.lastModified);
           break;
         case "url":
-          if (!("feedUrl" in aExpected))
-            Assert.equal(aNode.uri, aExpected.url);
+          Assert.equal(aNode.uri, aExpected.url);
           break;
         case "icon":
           let {data} = await getFaviconDataForPage(aExpected.url);
           let base64Icon = "data:image/png;base64," +
                            base64EncodeString(String.fromCharCode.apply(String, data));
           Assert.ok(base64Icon == aExpected.icon);
           break;
         case "keyword": {
@@ -313,21 +312,17 @@ function checkItem(aExpected, aNode) {
           Assert.equal(entry.postData, aExpected.postData);
           break;
         }
         case "charset":
           let pageInfo = await PlacesUtils.history.fetch(aNode.uri, {includeAnnotations: true});
           Assert.equal(pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), aExpected.charset);
           break;
         case "feedUrl":
-          let livemark = await PlacesUtils.livemarks.getLivemark({ id });
-          if (aExpected.url) {
-            Assert.equal(livemark.siteURI.spec, aExpected.url);
-          }
-          Assert.equal(livemark.feedURI.spec, aExpected.feedUrl);
+          // No more supported.
           break;
         case "children":
           let folder = aNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
           Assert.equal(folder.hasChildren, aExpected.children.length > 0);
           folder.containerOpen = true;
           Assert.equal(folder.childCount, aExpected.children.length);
 
           for (let index = 0; index < aExpected.children.length; index++) {
--- a/toolkit/components/places/tests/unit/test_bookmarks_html_corrupt.js
+++ b/toolkit/components/places/tests/unit/test_bookmarks_html_corrupt.js
@@ -84,33 +84,16 @@ var database_check = async function() {
   // clean up
   folderNode.containerOpen = false;
   root.containerOpen = false;
 
   // BOOKMARKS TOOLBAR
   root = PlacesUtils.getFolderContents(PlacesUtils.bookmarks.toolbarGuid).root;
   Assert.equal(root.childCount, 3);
 
-  // For now some promises are resolved later, so we can't guarantee an order.
-  let foundLivemark = false;
-  for (let i = 0; i < root.childCount; ++i) {
-    let node = root.getChild(i);
-    if (node.title == "Latest Headlines") {
-      foundLivemark = true;
-      Assert.equal("Latest Headlines", node.title);
-
-      let livemark = await PlacesUtils.livemarks.getLivemark({ guid: node.bookmarkGuid });
-      Assert.equal("http://en-us.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/",
-                   livemark.siteURI.spec);
-      Assert.equal("http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml",
-                   livemark.feedURI.spec);
-    }
-  }
-  Assert.ok(foundLivemark);
-
   // cleanup
   root.containerOpen = false;
 
   // UNFILED BOOKMARKS
   root = PlacesUtils.getFolderContents(PlacesUtils.bookmarks.unfiledGuid).root;
   Assert.equal(root.childCount, 1);
   root.containerOpen = false;
 
--- a/toolkit/components/places/tests/unit/test_bookmarks_json.js
+++ b/toolkit/components/places/tests/unit/test_bookmarks_json.js
@@ -60,18 +60,21 @@ var test_bookmarks = {
   toolbar: [
     { guid: "OCyeUO5uu9FB",
       title: "Getting Started",
       url: "http://en-us.www.mozilla.com/en-US/firefox/central/",
       icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==",
     },
     { guid: "OCyeUO5uu9FR",
       title: "Latest Headlines",
-      url: "http://en-us.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/",
-      feedUrl: "http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml",
+      // This used to be a livemark, but we don't import them anymore, instead
+      // it will be imported as an empty folder, because the json format stores
+      // it like that: an empty folder with a couple annotations. Since
+      // annotations will go away, there won't be a clean way to import it as a
+      // bookmark instead.
       // Note: date gets truncated to milliseconds, whereas the value in bookmarks.json
       // has full microseconds.
       dateAdded: 1361551979451000,
       lastModified: 1361551979457000,
     },
   ],
   unfiled: [
     { guid: "OCyeUO5uu9FW",
@@ -165,17 +168,16 @@ async function testImportedBookmarks() {
       await checkItem(items[key], root.getChild(key));
     }
 
     root.containerOpen = false;
   }
 }
 
 async function checkItem(aExpected, aNode) {
-  let id = aNode.itemId;
   let bookmark = await PlacesUtils.bookmarks.fetch(aNode.bookmarkGuid);
 
   for (let prop in aExpected) {
     switch (prop) {
       case "type":
         Assert.equal(aNode.type, aExpected.type);
         break;
       case "title":
@@ -185,18 +187,17 @@ async function checkItem(aExpected, aNod
         Assert.equal(PlacesUtils.toPRTime(bookmark.dateAdded),
                      aExpected.dateAdded);
         break;
       case "lastModified":
         Assert.equal(PlacesUtils.toPRTime(bookmark.lastModified),
                      aExpected.lastModified);
         break;
       case "url":
-        if (!("feedUrl" in aExpected))
-          Assert.equal(aNode.uri, aExpected.url);
+        Assert.equal(aNode.uri, aExpected.url);
         break;
       case "icon":
         let {data} = await getFaviconDataForPage(aExpected.url);
         let base64Icon = "data:image/png;base64," +
                          base64EncodeString(String.fromCharCode.apply(String, data));
         Assert.equal(base64Icon, aExpected.icon);
         break;
       case "keyword": {
@@ -211,21 +212,16 @@ async function checkItem(aExpected, aNod
         let entry = await PlacesUtils.keywords.fetch({ url: aNode.uri });
         Assert.equal(entry.postData, aExpected.postData);
         break;
       }
       case "charset":
         let pageInfo = await PlacesUtils.history.fetch(aNode.uri, {includeAnnotations: true});
         Assert.equal(pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), aExpected.charset);
         break;
-      case "feedUrl":
-        let livemark = await PlacesUtils.livemarks.getLivemark({ id });
-        Assert.equal(livemark.siteURI.spec, aExpected.url);
-        Assert.equal(livemark.feedURI.spec, aExpected.feedUrl);
-        break;
       case "children":
         let folder = aNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
         Assert.equal(folder.hasChildren, aExpected.children.length > 0);
         folder.containerOpen = true;
         Assert.equal(folder.childCount, aExpected.children.length);
 
         for (let index = 0; index < aExpected.children.length; index++) {
           await checkItem(aExpected.children[index], folder.getChild(index));
--- a/toolkit/components/places/tests/unit/xpcshell.ini
+++ b/toolkit/components/places/tests/unit/xpcshell.ini
@@ -2,17 +2,16 @@
 head = head_bookmarks.js
 firefox-appdir = browser
 support-files =
   bookmarks.corrupt.html
   bookmarks.json
   bookmarks_corrupt.json
   bookmarks.preplaces.html
   bookmarks_html_singleframe.html
-  livemark.xml
   mobile_bookmarks_folder_import.json
   mobile_bookmarks_folder_merge.json
   mobile_bookmarks_multiple_folders.json
   mobile_bookmarks_root_import.json
   mobile_bookmarks_root_merge.json
   places.sparse.sqlite
 
 [test_000_frecency.js]
@@ -75,17 +74,16 @@ skip-if = appname == "thunderbird"
 [test_keywords.js]
 [test_lastModified.js]
 [test_markpageas.js]
 [test_metadata.js]
 [test_missing_builtin_folders.js]
 support-files = missingBuiltIn.sqlite
 [test_missing_root_folder.js]
 support-files = noRoot.sqlite
-[test_mozIAsyncLivemarks.js]
 [test_multi_word_tags.js]
 [test_nsINavHistoryViewer.js]
 [test_null_interfaces.js]
 [test_onItemChanged_tags.js]
 [test_origins.js]
 [test_origins_parsing.js]
 [test_pageGuid_bookmarkGuid.js]
 [test_frecency_observers.js]
--- a/toolkit/modules/addons/WebRequest.jsm
+++ b/toolkit/modules/addons/WebRequest.jsm
@@ -131,17 +131,17 @@ class HeaderChanger {
         value = String.fromCharCode(...binaryValue);
       }
 
       let lowerCaseName = name.toLowerCase();
       let original = origHeaders.get(lowerCaseName);
 
       if (!original || value !== original.value) {
         let shouldMerge = headersAlreadySet.has(lowerCaseName);
-        this.setHeader(name, value, shouldMerge, opts);
+        this.setHeader(name, value, shouldMerge, opts, lowerCaseName);
       }
 
       headersAlreadySet.add(lowerCaseName);
     }
   }
 }
 
 const checkRestrictedHeaderValue = (value, opts = {}) => {
@@ -153,34 +153,34 @@ const checkRestrictedHeaderValue = (valu
   }
 
   if (WebExtensionPolicy.isRestrictedURI(uri)) {
     throw new Error(`Unable to set host header to restricted url.`);
   }
 };
 
 class RequestHeaderChanger extends HeaderChanger {
-  setHeader(name, value, merge, opts = {}) {
+  setHeader(name, value, merge, opts, lowerCaseName) {
     try {
-      if (name === "host") {
+      if (value && lowerCaseName === "host") {
         checkRestrictedHeaderValue(value, opts);
       }
       this.channel.setRequestHeader(name, value, merge);
     } catch (e) {
       Cu.reportError(new Error(`Error setting request header ${name}: ${e}`));
     }
   }
 
   readHeaders() {
     return this.channel.getRequestHeaders();
   }
 }
 
 class ResponseHeaderChanger extends HeaderChanger {
-  setHeader(name, value, merge, opts = {}) {
+  setHeader(name, value, merge, opts, lowerCaseName) {
     try {
       this.channel.setResponseHeader(name, value, merge);
     } catch (e) {
       Cu.reportError(new Error(`Error setting response header ${name}: ${e}`));
     }
   }
 
   readHeaders() {
--- a/xpcom/ds/StaticAtoms.py
+++ b/xpcom/ds/StaticAtoms.py
@@ -2184,17 +2184,17 @@ STATIC_ATOMS = [
     Atom("onsourceended", "onsourceended"),
     Atom("onsourceclosed", "onsourceclosed"),
     Atom("onupdatestart", "onupdatestart"),
     Atom("onupdate", "onupdate"),
     Atom("onupdateend", "onupdateend"),
     Atom("onaddsourcebuffer", "onaddsourcebuffer"),
     Atom("onremovesourcebuffer", "onremovesourcebuffer"),
 
-    # RDF
+    # RDF (not used by mozilla-central, but still used by comm-central)
     Atom("about", "about"),
     Atom("ID", "ID"),
     Atom("nodeID", "nodeID"),
     Atom("aboutEach", "aboutEach"),
     Atom("resource", "resource"),
     Atom("RDF", "RDF"),
     Atom("Description", "Description"),
     Atom("Bag", "Bag"),