diff --git a/b2g/app/b2g.js b/b2g/app/b2g.js
index 13d99dfbbc0..951bf358d0a 100644
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -319,7 +319,7 @@ pref("media.fragmented-mp4.gonk.enabled", true);
pref("media.video-queue.default-size", 3);
// optimize images' memory usage
-pref("image.mem.decodeondraw", true);
+pref("image.mem.decodeondraw", false);
pref("image.mem.allow_locking_in_content_processes", false); /* don't allow image locking */
// Limit the surface cache to 1/8 of main memory or 128MB, whichever is smaller.
// Almost everything that was factored into 'max_decoded_image_kb' is now stored
diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml
index 0931cffbf8b..9006d3bcd51 100644
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index 8df3d024855..08f9699d055 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -19,7 +19,7 @@
-
+
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index 27c9f761096..1b0893f608f 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -17,7 +17,7 @@
-
+
diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml
index 0194695809f..b2e9feaff5c 100644
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index 8df3d024855..08f9699d055 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -19,7 +19,7 @@
-
+
diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml
index 4ca1b3822b1..6f748f41b8d 100644
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml
index 5344147e21d..cb27a1a0b6d 100644
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -17,7 +17,7 @@
-
+
diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index e4025853310..c85110c777b 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
{
"git": {
- "git_revision": "0244121522343877d65a69377226a836688e3004",
+ "git_revision": "a0e71e61922bde009a3b6714cbe965021d3279f1",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
- "revision": "33d9ca589ca27af7f98b29b97a232ca599f111fe",
+ "revision": "0829f98e30c6f7795f66052d32e25456eb54bda5",
"repo_path": "integration/gaia-central"
}
diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml
index 163972b68a6..6efea03d035 100644
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -17,7 +17,7 @@
-
+
diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml
index dff4eb54510..75f5f8292c9 100644
--- a/b2g/config/nexus-5-l/sources.xml
+++ b/b2g/config/nexus-5-l/sources.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js
index 9778aaeedc9..d8019c1f072 100644
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1438,6 +1438,7 @@ pref("devtools.profiler.ui.show-idle-blocks", true);
// The default Performance UI settings
pref("devtools.performance.ui.invert-call-tree", true);
+pref("devtools.performance.ui.invert-flame-graph", false);
pref("devtools.performance.ui.flatten-tree-recursion", true);
pref("devtools.performance.ui.show-platform-data", false);
pref("devtools.performance.ui.show-idle-blocks", true);
diff --git a/browser/base/content/browser-eme.js b/browser/base/content/browser-eme.js
new file mode 100644
index 00000000000..0d82be02c6c
--- /dev/null
+++ b/browser/base/content/browser-eme.js
@@ -0,0 +1,36 @@
+# -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+# 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/.
+
+function gEMEListener(msg /*{target: browser, data: data} */) {
+ let browser = msg.target;
+ let notificationId = "drmContentPlaying";
+ // Don't need to show if disabled, nor reshow if it's already there
+ if (!Services.prefs.getBoolPref("browser.eme.ui.enabled") ||
+ PopupNotifications.getNotification(notificationId, browser)) {
+ return;
+ }
+
+ let msgId = "emeNotifications.drmContentPlaying.message";
+ let brandName = document.getElementById("bundle_brand").getString("brandShortName");
+ let message = gNavigatorBundle.getFormattedString(msgId, [msg.data.drmProvider, brandName]);
+ let anchorId = "eme-notification-icon";
+
+ let mainAction = {
+ label: gNavigatorBundle.getString("emeNotifications.drmContentPlaying.button.label"),
+ accessKey: gNavigatorBundle.getString("emeNotifications.drmContentPlaying.button.accesskey"),
+ callback: function() { openPreferences("paneContent"); },
+ dismiss: true
+ };
+ let options = {
+ dismissed: true,
+ eventCallback: aTopic => aTopic == "swapping",
+ };
+ PopupNotifications.show(browser, notificationId, message, anchorId, mainAction, null, options);
+};
+
+window.messageManager.addMessageListener("EMEVideo:MetadataLoaded", gEMEListener);
+window.addEventListener("unload", function() {
+ window.messageManager.removeMessageListener("EMEVideo:MetadataLoaded", gEMEListener);
+}, false);
diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
index f18d2e5555e..f46347a3390 100644
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -214,6 +214,7 @@ let gInitialPages = [
#include browser-ctrlTab.js
#include browser-customization.js
#include browser-devedition.js
+#include browser-eme.js
#include browser-feeds.js
#include browser-fullScreen.js
#include browser-fullZoom.js
diff --git a/browser/base/content/browser.xul b/browser/base/content/browser.xul
index 2d0d7e2719c..db1a63c164a 100644
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -822,6 +822,7 @@
+
+
+
+ %webideDTD;
+]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+ &wifi_auth_scan_request;
+
+
+
+
+
+
+
diff --git a/browser/devtools/webide/modules/app-manager.js b/browser/devtools/webide/modules/app-manager.js
index 6206f0bbd09..7db179da8af 100644
--- a/browser/devtools/webide/modules/app-manager.js
+++ b/browser/devtools/webide/modules/app-manager.js
@@ -365,7 +365,10 @@ let AppManager = exports.AppManager = {
try {
// Reset the connection's state to defaults
this.connection.resetOptions();
- deferred.resolve(this.selectedRuntime.connect(this.connection));
+ // Only watch for errors here. Final resolution occurs above, once
+ // we've reached the CONNECTED state.
+ this.selectedRuntime.connect(this.connection)
+ .then(null, e => deferred.reject(e));
} catch(e) {
deferred.reject(e);
}
diff --git a/browser/devtools/webide/modules/runtimes.js b/browser/devtools/webide/modules/runtimes.js
index 4222127a1d9..d6d828cc31d 100644
--- a/browser/devtools/webide/modules/runtimes.js
+++ b/browser/devtools/webide/modules/runtimes.js
@@ -2,7 +2,7 @@
* 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/. */
-const {Cu} = require("chrome");
+const {Cu, Ci} = require("chrome");
const {Devices} = Cu.import("resource://gre/modules/devtools/Devices.jsm");
const {Services} = Cu.import("resource://gre/modules/Services.jsm");
const {Simulator} = Cu.import("resource://gre/modules/devtools/Simulator.jsm");
@@ -11,6 +11,10 @@ const {DebuggerServer} = require("resource://gre/modules/devtools/dbg-server.jsm
const discovery = require("devtools/toolkit/discovery/discovery");
const EventEmitter = require("devtools/toolkit/event-emitter");
const promise = require("promise");
+loader.lazyRequireGetter(this, "AuthenticationResult",
+ "devtools/toolkit/security/auth", true);
+loader.lazyRequireGetter(this, "DevToolsUtils",
+ "devtools/toolkit/DevToolsUtils");
const Strings = Services.strings.createBundle("chrome://browser/locale/devtools/webide.properties");
@@ -448,7 +452,7 @@ WiFiRuntime.prototype = {
return promise.reject(new Error("Can't find device: " + this.name));
}
connection.advertisement = service;
- // TODO: Customize client authentication UX
+ connection.authenticator.sendOOB = this.sendOOB;
connection.connect();
return promise.resolve();
},
@@ -458,6 +462,81 @@ WiFiRuntime.prototype = {
get name() {
return this.deviceName;
},
+
+ /**
+ * During OOB_CERT authentication, a notification dialog like this is used to
+ * to display a token which the user must transfer through some mechanism to the
+ * server to authenticate the devices.
+ *
+ * This implementation presents the token as text for the user to transfer
+ * manually. For a mobile device, you should override this implementation with
+ * something more convenient, such as displaying a QR code.
+ *
+ * This method receives an object containing:
+ * @param host string
+ * The host name or IP address of the debugger server.
+ * @param port number
+ * The port number of the debugger server.
+ * @param cert object (optional)
+ * The server's cert details.
+ * @param authResult AuthenticationResult
+ * Authentication result sent from the server.
+ * @param oob object (optional)
+ * The token data to be transferred during OOB_CERT step 8:
+ * * sha256: hash(ClientCert)
+ * * k : K(random 128-bit number)
+ * @return object containing:
+ * * close: Function to hide the notification
+ */
+ sendOOB(session) {
+ const WINDOW_ID = "devtools:wifi-auth";
+ let { authResult } = session;
+ // Only show in the PENDING state
+ if (authResult != AuthenticationResult.PENDING) {
+ throw new Error("Expected PENDING result, got " + authResult);
+ }
+
+ // Listen for the window our prompt opens, so we can close it programatically
+ let promptWindow;
+ let windowListener = {
+ onOpenWindow(xulWindow) {
+ let win = xulWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindow);
+ win.addEventListener("load", function listener() {
+ win.removeEventListener("load", listener, false);
+ if (win.document.documentElement.getAttribute("id") != WINDOW_ID) {
+ return;
+ }
+ // Found the window
+ promptWindow = win;
+ Services.wm.removeListener(windowListener);
+ }, false);
+ },
+ onCloseWindow() {},
+ onWindowTitleChange() {}
+ };
+ Services.wm.addListener(windowListener);
+
+ // |openDialog| is typically a blocking API, so |executeSoon| to get around this
+ DevToolsUtils.executeSoon(() => {
+ let win = Services.wm.getMostRecentWindow("devtools:webide");
+ let width = win.outerWidth * 0.8;
+ let height = win.outerHeight * 0.5;
+ win.openDialog("chrome://webide/content/wifi-auth.xhtml",
+ WINDOW_ID,
+ "modal=yes,width=" + width + ",height=" + height, session);
+ });
+
+ return {
+ close() {
+ if (!promptWindow) {
+ return;
+ }
+ promptWindow.close();
+ promptWindow = null;
+ }
+ };
+ }
};
// For testing use only
diff --git a/browser/devtools/webide/themes/jar.mn b/browser/devtools/webide/themes/jar.mn
index e9b6aec8465..76174fd0aad 100644
--- a/browser/devtools/webide/themes/jar.mn
+++ b/browser/devtools/webide/themes/jar.mn
@@ -16,3 +16,4 @@ webide.jar:
skin/permissionstable.css (permissionstable.css)
skin/monitor.css (monitor.css)
skin/config-view.css (config-view.css)
+ skin/wifi-auth.css (wifi-auth.css)
diff --git a/browser/devtools/webide/themes/wifi-auth.css b/browser/devtools/webide/themes/wifi-auth.css
new file mode 100644
index 00000000000..1a9b02336bc
--- /dev/null
+++ b/browser/devtools/webide/themes/wifi-auth.css
@@ -0,0 +1,60 @@
+/* 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/. */
+
+html, body {
+ background: white;
+}
+
+body {
+ display: flex;
+ flex-direction: column;
+ height: 90%;
+}
+
+div {
+ margin-bottom: 1em;
+}
+
+#qr-code {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+#qr-code-wrapper {
+ flex: 1;
+ width: 100%;
+ margin: 2em 0;
+ text-align: center;
+}
+
+#qr-code img {
+ height: 100%;
+}
+
+.toggle-scanner {
+ color: #4C9ED9;
+ font-size: small;
+ cursor: pointer;
+ border-bottom: 1px dotted;
+}
+
+#token {
+ display: none;
+}
+
+body[token] > #token {
+ display: flex;
+ flex-direction: column;
+}
+
+body[token] > #qr-code {
+ display: none;
+}
+
+#token pre,
+#token a {
+ align-self: center;
+}
diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in
index 812b56a4412..500eb80f929 100644
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -400,6 +400,7 @@
@RESPATH@/components/toolkitsearch.manifest
@RESPATH@/components/nsSearchService.js
@RESPATH@/components/nsSearchSuggestions.js
+@RESPATH@/components/nsSidebar.js
@RESPATH@/components/passwordmgr.manifest
@RESPATH@/components/nsLoginInfo.js
@RESPATH@/components/nsLoginManager.js
@@ -419,8 +420,6 @@
@RESPATH@/components/nsHelperAppDlg.js
@RESPATH@/components/NetworkGeolocationProvider.manifest
@RESPATH@/components/NetworkGeolocationProvider.js
-@RESPATH@/browser/components/nsSidebar.manifest
-@RESPATH@/browser/components/nsSidebar.js
@RESPATH@/components/extensions.manifest
@RESPATH@/components/addonManager.js
@RESPATH@/components/amContentHandler.js
diff --git a/browser/locales/en-US/chrome/browser/browser.properties b/browser/locales/en-US/chrome/browser/browser.properties
index a71a03eea1f..9ec8b61b126 100644
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -591,6 +591,11 @@ getUserMedia.sharingMenuMicrophoneWindow = %S (microphone and window)
# origin for the sharing menu if no readable origin could be deduced from the URL.
getUserMedia.sharingMenuUnknownHost = Unknown origin
+# LOCALIZATION NOTE(emeNotifications.drmContentPlaying.message): %1$S is the vendor name of the DRM that's in use, %2$S is brandShortName.
+emeNotifications.drmContentPlaying.message = Some audio or video on this site uses %1$S DRM software, which may limit what %2$S can let you do with it.
+emeNotifications.drmContentPlaying.button.label = Configure…
+emeNotifications.drmContentPlaying.button.accesskey = C
+
# LOCALIZATION NOTE - %S is brandShortName
slowStartup.message = %S seems slow… to… start.
slowStartup.helpButton.label = Learn How to Speed It Up
diff --git a/browser/locales/en-US/chrome/browser/devtools/profiler.dtd b/browser/locales/en-US/chrome/browser/devtools/profiler.dtd
index bf95f4fb524..d0a3242916d 100644
--- a/browser/locales/en-US/chrome/browser/devtools/profiler.dtd
+++ b/browser/locales/en-US/chrome/browser/devtools/profiler.dtd
@@ -81,6 +81,11 @@
+
+
+
+
diff --git a/browser/locales/en-US/chrome/browser/devtools/webide.dtd b/browser/locales/en-US/chrome/browser/devtools/webide.dtd
index 02823c37277..947d338ba33 100644
--- a/browser/locales/en-US/chrome/browser/devtools/webide.dtd
+++ b/browser/locales/en-US/chrome/browser/devtools/webide.dtd
@@ -173,3 +173,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/browser/modules/ContentObservers.jsm b/browser/modules/ContentObservers.jsm
new file mode 100644
index 00000000000..15323b31517
--- /dev/null
+++ b/browser/modules/ContentObservers.jsm
@@ -0,0 +1,47 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* 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/. */
+
+/**
+ * This module is for small observers that we want to register once per content
+ * process, usually in order to forward content-based observer service notifications
+ * to the chrome process through message passing. Using a JSM avoids having them
+ * in content.js and thereby registering N observers for N open tabs, which is bad
+ * for perf.
+ */
+
+"use strict";
+
+this.EXPORTED_SYMBOLS = [];
+
+const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+
+Cu.import("resource://gre/modules/Services.jsm");
+
+let gEMEUIObserver = function(subject, topic, data) {
+ let win = subject.ownerDocument.defaultView.top;
+ let mm = getMessageManagerForWindow(win);
+ if (mm) {
+ mm.sendAsyncMessage("EMEVideo:MetadataLoaded", {
+ // bug 1129370 covers making this the actual DRM provider inferred from
+ // either |subject| or |data| here.
+ drmProvider: "Adobe"
+ });
+ }
+};
+
+function getMessageManagerForWindow(aContentWindow) {
+ let ir = aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDocShell)
+ .sameTypeRootTreeItem
+ .QueryInterface(Ci.nsIInterfaceRequestor);
+ try {
+ // If e10s is disabled, this throws NS_NOINTERFACE for closed tabs.
+ return ir.getInterface(Ci.nsIContentFrameMessageManager);
+ } catch(e if e.result == Cr.NS_NOINTERFACE) {
+ return null;
+ }
+}
+
+Services.obs.addObserver(gEMEUIObserver, "media-eme-metadataloaded", false);
diff --git a/browser/modules/moz.build b/browser/modules/moz.build
index 153b4a7e564..3bfdc068202 100644
--- a/browser/modules/moz.build
+++ b/browser/modules/moz.build
@@ -16,6 +16,7 @@ EXTRA_JS_MODULES += [
'Chat.jsm',
'ContentClick.jsm',
'ContentLinkHandler.jsm',
+ 'ContentObservers.jsm',
'ContentSearch.jsm',
'ContentWebRTC.jsm',
'CustomizationTabPreloader.jsm',
diff --git a/browser/themes/linux/browser.css b/browser/themes/linux/browser.css
index 5ba2dbf6b30..ce760232d66 100644
--- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css
@@ -2185,6 +2185,17 @@ chatbox {
border-top-right-radius: 2.5px;
}
+/* EME notifications */
+
+.popup-notification-icon[popupid="drmContentPlaying"],
+#eme-notification-icon {
+ list-style-image: url("chrome://browser/skin/drm-icon.svg#chains");
+}
+
+#eme-notification-icon:hover:active {
+ list-style-image: url("chrome://browser/skin/drm-icon.svg#chains-pressed");
+}
+
/* Customization mode */
%include ../shared/customizableui/customizeMode.inc.css
diff --git a/browser/themes/linux/jar.mn b/browser/themes/linux/jar.mn
index 1bfa3112a83..479a188c9ff 100644
--- a/browser/themes/linux/jar.mn
+++ b/browser/themes/linux/jar.mn
@@ -30,6 +30,7 @@ browser.jar:
skin/classic/browser/content-contextmenu.svg
skin/classic/browser/dots.png (../shared/dots.png)
skin/classic/browser/dots@2x.png (../shared/dots@2x.png)
+ skin/classic/browser/drm-icon.svg (../shared/drm-icon.svg)
* skin/classic/browser/engineManager.css
skin/classic/browser/fullscreen-darknoise.png
skin/classic/browser/Geolocation-16.png
diff --git a/browser/themes/osx/browser.css b/browser/themes/osx/browser.css
index 0312b384bb6..3645206cfda 100644
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -4612,6 +4612,17 @@ window > chatbox {
border-bottom-right-radius: @toolbarbuttonCornerRadius@;
}
+/* EME notifications */
+
+.popup-notification-icon[popupid="drmContentPlaying"],
+#eme-notification-icon {
+ list-style-image: url("chrome://browser/skin/drm-icon.svg#chains");
+}
+
+#eme-notification-icon:hover:active {
+ list-style-image: url("chrome://browser/skin/drm-icon.svg#chains-pressed");
+}
+
/* Customization mode */
%include ../shared/customizableui/customizeMode.inc.css
diff --git a/browser/themes/osx/jar.mn b/browser/themes/osx/jar.mn
index 3437e71fbed..51ffe4813c1 100644
--- a/browser/themes/osx/jar.mn
+++ b/browser/themes/osx/jar.mn
@@ -30,6 +30,7 @@ browser.jar:
skin/classic/browser/content-contextmenu.svg
skin/classic/browser/dots.png (../shared/dots.png)
skin/classic/browser/dots@2x.png (../shared/dots@2x.png)
+ skin/classic/browser/drm-icon.svg (../shared/drm-icon.svg)
* skin/classic/browser/engineManager.css (engineManager.css)
skin/classic/browser/fullscreen-darknoise.png
skin/classic/browser/Geolocation-16.png
diff --git a/browser/themes/shared/drm-icon.svg b/browser/themes/shared/drm-icon.svg
new file mode 100644
index 00000000000..03b279cd844
--- /dev/null
+++ b/browser/themes/shared/drm-icon.svg
@@ -0,0 +1,47 @@
+
+
diff --git a/browser/themes/shared/incontentprefs/preferences.inc.css b/browser/themes/shared/incontentprefs/preferences.inc.css
index 1629c844891..c5349d5e6e3 100644
--- a/browser/themes/shared/incontentprefs/preferences.inc.css
+++ b/browser/themes/shared/incontentprefs/preferences.inc.css
@@ -153,15 +153,19 @@ treecol {
white-space: nowrap;
}
-#startupTable > tr > .content-cell {
- display: flex;
+#startupTable > tr > .content-cell > menulist,
+#startupTable > tr > .content-cell > textbox {
+ width: calc(100% - 8px);
+ margin-left: 4px;
+ margin-right: 4px;
}
#startupTable > tr > .homepage-buttons {
+ display: flex;
flex-wrap: wrap;
}
-#startupTable > tr > td > .content-cell-item {
+#startupTable > tr > .homepage-buttons > .content-cell-item {
flex-grow: 1;
}
diff --git a/browser/themes/windows/browser.css b/browser/themes/windows/browser.css
index 204c3925747..67b772ddac9 100644
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -2807,6 +2807,17 @@ chatbox {
border-top-right-radius: 2.5px;
}
+/* EME notifications */
+
+.popup-notification-icon[popupid="drmContentPlaying"],
+#eme-notification-icon {
+ list-style-image: url("chrome://browser/skin/drm-icon.svg#chains");
+}
+
+#eme-notification-icon:hover:active {
+ list-style-image: url("chrome://browser/skin/drm-icon.svg#chains-pressed");
+}
+
/* Customization mode */
%include ../shared/customizableui/customizeMode.inc.css
diff --git a/browser/themes/windows/jar.mn b/browser/themes/windows/jar.mn
index 8cd019284f3..95ab930a9c8 100644
--- a/browser/themes/windows/jar.mn
+++ b/browser/themes/windows/jar.mn
@@ -32,6 +32,7 @@ browser.jar:
skin/classic/browser/content-contextmenu.svg
skin/classic/browser/dots.png (../shared/dots.png)
skin/classic/browser/dots@2x.png (../shared/dots@2x.png)
+ skin/classic/browser/drm-icon.svg (../shared/drm-icon.svg)
* skin/classic/browser/engineManager.css
skin/classic/browser/fullscreen-darknoise.png
skin/classic/browser/Geolocation-16.png
@@ -494,6 +495,7 @@ browser.jar:
* skin/classic/aero/browser/content-contextmenu.svg
skin/classic/aero/browser/dots.png (../shared/dots.png)
skin/classic/aero/browser/dots@2x.png (../shared/dots@2x.png)
+ skin/classic/aero/browser/drm-icon.svg (../shared/drm-icon.svg)
* skin/classic/aero/browser/engineManager.css
skin/classic/aero/browser/fullscreen-darknoise.png
skin/classic/aero/browser/Geolocation-16.png
diff --git a/dom/canvas/WebGLContext.cpp b/dom/canvas/WebGLContext.cpp
index 38420ff232e..749621074af 100644
--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -505,7 +505,7 @@ IsFeatureInBlacklist(const nsCOMPtr& gfxInfo, int32_t feature)
static already_AddRefed
CreateHeadlessNativeGL(bool forceEnabled, const nsCOMPtr& gfxInfo,
- bool requireCompatProfile, WebGLContext* webgl)
+ WebGLContext* webgl)
{
if (!forceEnabled &&
IsFeatureInBlacklist(gfxInfo, nsIGfxInfo::FEATURE_WEBGL_OPENGL))
@@ -515,7 +515,7 @@ CreateHeadlessNativeGL(bool forceEnabled, const nsCOMPtr& gfxInfo,
return nullptr;
}
- nsRefPtr gl = gl::GLContextProvider::CreateHeadless(requireCompatProfile);
+ nsRefPtr gl = gl::GLContextProvider::CreateHeadless();
if (!gl) {
webgl->GenerateWarning("Error during native OpenGL init.");
return nullptr;
@@ -530,7 +530,7 @@ CreateHeadlessNativeGL(bool forceEnabled, const nsCOMPtr& gfxInfo,
// Eventually, we want to be able to pick ANGLE-EGL or native EGL.
static already_AddRefed
CreateHeadlessANGLE(bool forceEnabled, const nsCOMPtr& gfxInfo,
- bool requireCompatProfile, WebGLContext* webgl)
+ WebGLContext* webgl)
{
nsRefPtr gl;
@@ -543,7 +543,7 @@ CreateHeadlessANGLE(bool forceEnabled, const nsCOMPtr& gfxInfo,
return nullptr;
}
- gl = gl::GLContextProviderEGL::CreateHeadless(requireCompatProfile);
+ gl = gl::GLContextProviderEGL::CreateHeadless();
if (!gl) {
webgl->GenerateWarning("Error during ANGLE OpenGL init.");
return nullptr;
@@ -555,13 +555,13 @@ CreateHeadlessANGLE(bool forceEnabled, const nsCOMPtr& gfxInfo,
}
static already_AddRefed
-CreateHeadlessEGL(bool forceEnabled, bool requireCompatProfile,
+CreateHeadlessEGL(bool forceEnabled, const nsCOMPtr& gfxInfo,
WebGLContext* webgl)
{
nsRefPtr gl;
#ifdef ANDROID
- gl = gl::GLContextProviderEGL::CreateHeadless(requireCompatProfile);
+ gl = gl::GLContextProviderEGL::CreateHeadless();
if (!gl) {
webgl->GenerateWarning("Error during EGL OpenGL init.");
return nullptr;
@@ -583,22 +583,16 @@ CreateHeadlessGL(bool forceEnabled, const nsCOMPtr& gfxInfo,
if (PR_GetEnv("MOZ_WEBGL_FORCE_OPENGL"))
disableANGLE = true;
- bool requireCompatProfile = webgl->IsWebGL2() ? false : true;
-
nsRefPtr gl;
if (preferEGL)
- gl = CreateHeadlessEGL(forceEnabled, requireCompatProfile, webgl);
+ gl = CreateHeadlessEGL(forceEnabled, gfxInfo, webgl);
- if (!gl && !disableANGLE) {
- gl = CreateHeadlessANGLE(forceEnabled, gfxInfo, requireCompatProfile,
- webgl);
- }
+ if (!gl && !disableANGLE)
+ gl = CreateHeadlessANGLE(forceEnabled, gfxInfo, webgl);
- if (!gl) {
- gl = CreateHeadlessNativeGL(forceEnabled, gfxInfo,
- requireCompatProfile, webgl);
- }
+ if (!gl)
+ gl = CreateHeadlessNativeGL(forceEnabled, gfxInfo, webgl);
return gl.forget();
}
diff --git a/dom/canvas/WebGLContext.h b/dom/canvas/WebGLContext.h
index fdaada5f80b..dabdd737782 100644
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -1209,10 +1209,9 @@ protected:
// -------------------------------------------------------------------------
// WebGL 2 specifics (implemented in WebGL2Context.cpp)
-public:
+
virtual bool IsWebGL2() const = 0;
-protected:
bool InitWebGL2();
// -------------------------------------------------------------------------
diff --git a/dom/canvas/WebGLContextGL.cpp b/dom/canvas/WebGLContextGL.cpp
index 1e4d4c1b370..999b71b67e4 100644
--- a/dom/canvas/WebGLContextGL.cpp
+++ b/dom/canvas/WebGLContextGL.cpp
@@ -2106,6 +2106,7 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
// if we're reading alpha, we may need to do fixup. Note that we don't allow
// GL_ALPHA to readpixels currently, but we had the code written for it already.
+
const bool formatHasAlpha = format == LOCAL_GL_ALPHA ||
format == LOCAL_GL_RGBA;
if (!formatHasAlpha)
diff --git a/dom/canvas/WebGLContextUtils.cpp b/dom/canvas/WebGLContextUtils.cpp
index caba53cac18..b0e02a18577 100644
--- a/dom/canvas/WebGLContextUtils.cpp
+++ b/dom/canvas/WebGLContextUtils.cpp
@@ -1117,12 +1117,11 @@ WebGLContext::AssertCachedState()
AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_CLEAR_VALUE, mStencilClearValue);
GLint stencilBits = 0;
- if (GetStencilBits(&stencilBits)) {
- const GLuint stencilRefMask = (1 << stencilBits) - 1;
+ gl->fGetIntegerv(LOCAL_GL_STENCIL_BITS, &stencilBits);
+ const GLuint stencilRefMask = (1 << stencilBits) - 1;
- AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_REF, stencilRefMask, mStencilRefFront);
- AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_REF, stencilRefMask, mStencilRefBack);
- }
+ AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_REF, stencilRefMask, mStencilRefFront);
+ AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_REF, stencilRefMask, mStencilRefBack);
// GLES 3.0.4, $4.1.4, p177:
// [...] the front and back stencil mask are both set to the value `2^s - 1`, where
diff --git a/dom/canvas/WebGLContextValidate.cpp b/dom/canvas/WebGLContextValidate.cpp
index e942610793b..1dbc000a141 100644
--- a/dom/canvas/WebGLContextValidate.cpp
+++ b/dom/canvas/WebGLContextValidate.cpp
@@ -1779,8 +1779,8 @@ WebGLContext::InitAndValidateGL()
MakeContextCurrent();
- // For OpenGL compat. profiles, we always keep vertex attrib 0 array enabled.
- if (gl->IsCompatibilityProfile())
+ // on desktop OpenGL, we always keep vertex attrib 0 array enabled
+ if (!gl->IsGLES())
gl->fEnableVertexAttribArray(0);
if (MinCapabilityMode())
@@ -1889,7 +1889,7 @@ WebGLContext::InitAndValidateGL()
// Always 1 for GLES2
mMaxFramebufferColorAttachments = 1;
- if (gl->IsCompatibilityProfile()) {
+ if (!gl->IsGLES()) {
// gl_PointSize is always available in ES2 GLSL, but has to be
// specifically enabled on desktop GLSL.
gl->fEnable(LOCAL_GL_VERTEX_PROGRAM_POINT_SIZE);
diff --git a/dom/media/fmp4/android/AndroidDecoderModule.cpp b/dom/media/fmp4/android/AndroidDecoderModule.cpp
index bd00d07faa7..84fbd4ef3f5 100644
--- a/dom/media/fmp4/android/AndroidDecoderModule.cpp
+++ b/dom/media/fmp4/android/AndroidDecoderModule.cpp
@@ -179,7 +179,7 @@ protected:
return true;
}
- mGLContext = GLContextProvider::CreateHeadless(false);
+ mGLContext = GLContextProvider::CreateHeadless();
return mGLContext;
}
diff --git a/dom/plugins/base/nsNPAPIPluginInstance.cpp b/dom/plugins/base/nsNPAPIPluginInstance.cpp
index 9f94d76639d..811b75c31bf 100644
--- a/dom/plugins/base/nsNPAPIPluginInstance.cpp
+++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp
@@ -91,8 +91,9 @@ static nsRefPtr sPluginContext = nullptr;
static bool EnsureGLContext()
{
if (!sPluginContext) {
- bool requireCompatProfile = true;
- sPluginContext = GLContextProvider::CreateHeadless(requireCompatProfile);
+ gfxIntSize dummySize(16, 16);
+ sPluginContext = GLContextProvider::CreateOffscreen(dummySize,
+ SurfaceCaps::Any());
}
return sPluginContext != nullptr;
diff --git a/gfx/gl/GLContext.cpp b/gfx/gl/GLContext.cpp
index f84a47c54b0..b300ddff608 100644
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -8,7 +8,6 @@
#include
#include
#include
-#include
#include "GLContext.h"
#include "GLBlitHelper.h"
@@ -157,7 +156,8 @@ static const char *sExtensionNames[] = {
"GL_OES_texture_half_float",
"GL_OES_texture_half_float_linear",
"GL_OES_texture_npot",
- "GL_OES_vertex_array_object"
+ "GL_OES_vertex_array_object",
+ nullptr
};
static bool
@@ -501,8 +501,6 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
mInitialized = LoadSymbols(&symbols[0], trygl, prefix);
MakeCurrent();
if (mInitialized) {
- MOZ_ASSERT(mProfile != ContextProfile::Unknown);
-
uint32_t version = 0;
ParseGLVersion(this, &version);
@@ -658,15 +656,6 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
}
}
- if (IsFeatureProvidedByCoreSymbols(GLFeature::get_string_indexed)) {
- SymLoadStruct moreSymbols[] = {
- { (PRFuncPtr*) &mSymbols.fGetStringi, { "GetStringi", nullptr } },
- END_SYMBOLS
- };
-
- MOZ_ALWAYS_TRUE(LoadSymbols(moreSymbols, trygl, prefix));
- }
-
InitExtensions();
InitFeatures();
@@ -681,6 +670,12 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
MarkUnsupported(GLFeature::standard_derivatives);
}
+ if (Vendor() == GLVendor::Imagination &&
+ Renderer() == GLRenderer::SGX540) {
+ // Bug 980048
+ MarkExtensionUnsupported(OES_EGL_sync);
+ }
+
if (Renderer() == GLRenderer::MicrosoftBasicRenderDriver) {
// Bug 978966: on Microsoft's "Basic Render Driver" (software renderer)
// multisampling hardcodes blending with the default blendfunc, which breaks WebGL.
@@ -1473,13 +1468,10 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
// We're ready for final setup.
fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
- // TODO: Remove SurfaceCaps::any.
- if (mCaps.any) {
- mCaps.any = false;
- mCaps.color = true;
- mCaps.alpha = false;
- }
+ if (mCaps.any)
+ DetermineCaps();
+ UpdatePixelFormat();
UpdateGLFormats(mCaps);
mTexGarbageBin = new TextureGarbageBin(this);
@@ -1601,105 +1593,61 @@ GLContext::DebugCallback(GLenum source,
void
GLContext::InitExtensions()
{
- MOZ_ASSERT(IsCurrent());
+ MakeCurrent();
+ const char* extensions = (const char*)fGetString(LOCAL_GL_EXTENSIONS);
+ if (!extensions)
+ return;
- std::vector driverExtensionList;
+ InitializeExtensionsBitSet(mAvailableExtensions, extensions,
+ sExtensionNames);
- if (IsFeatureProvidedByCoreSymbols(GLFeature::get_string_indexed)) {
- GLuint count = 0;
- GetUIntegerv(LOCAL_GL_NUM_EXTENSIONS, &count);
- for (GLuint i = 0; i < count; i++) {
- // This is UTF-8.
- const char* rawExt = (const char*)fGetStringi(LOCAL_GL_EXTENSIONS, i);
+ if (WorkAroundDriverBugs() &&
+ Vendor() == GLVendor::Qualcomm) {
- // We CANNOT use nsDependentCString here, because the spec doesn't guarantee
- // that the pointers returned are different, only that their contents are.
- // On Flame, each of these index string queries returns the same address.
- driverExtensionList.push_back(nsCString(rawExt));
- }
- } else {
- MOZ_ALWAYS_TRUE(!fGetError());
- const char* rawExts = (const char*)fGetString(LOCAL_GL_EXTENSIONS);
- MOZ_ALWAYS_TRUE(!fGetError());
-
- if (rawExts) {
- nsDependentCString exts(rawExts);
- SplitByChar(exts, ' ', &driverExtensionList);
- }
+ // Some Adreno drivers do not report GL_OES_EGL_sync, but they really do support it.
+ MarkExtensionSupported(OES_EGL_sync);
}
- const bool shouldDumpExts = ShouldDumpExts();
- if (shouldDumpExts) {
- printf_stderr("%i GL driver extensions: (*: recognized)\n",
- (uint32_t)driverExtensionList.size());
+ if (WorkAroundDriverBugs() &&
+ Renderer() == GLRenderer::AndroidEmulator) {
+ // the Android emulator, which we use to run B2G reftests on,
+ // doesn't expose the OES_rgb8_rgba8 extension, but it seems to
+ // support it (tautologically, as it only runs on desktop GL).
+ MarkExtensionSupported(OES_rgb8_rgba8);
}
- MarkBitfieldByStrings(driverExtensionList, shouldDumpExts, sExtensionNames,
- &mAvailableExtensions);
-
- if (WorkAroundDriverBugs()) {
- if (Vendor() == GLVendor::Qualcomm) {
- // Some Adreno drivers do not report GL_OES_EGL_sync, but they really do support it.
- MarkExtensionSupported(OES_EGL_sync);
- }
-
- if (Vendor() == GLVendor::Imagination &&
- Renderer() == GLRenderer::SGX540)
- {
- // Bug 980048
- MarkExtensionUnsupported(OES_EGL_sync);
- }
-
- if (Renderer() == GLRenderer::AndroidEmulator) {
- // the Android emulator, which we use to run B2G reftests on,
- // doesn't expose the OES_rgb8_rgba8 extension, but it seems to
- // support it (tautologically, as it only runs on desktop GL).
- MarkExtensionSupported(OES_rgb8_rgba8);
- }
-
- if (Vendor() == GLVendor::VMware &&
- Renderer() == GLRenderer::GalliumLlvmpipe)
- {
- // The llvmpipe driver that is used on linux try servers appears to have
- // buggy support for s3tc/dxt1 compressed textures.
- // See Bug 975824.
- MarkExtensionUnsupported(EXT_texture_compression_s3tc);
- MarkExtensionUnsupported(EXT_texture_compression_dxt1);
- MarkExtensionUnsupported(ANGLE_texture_compression_dxt3);
- MarkExtensionUnsupported(ANGLE_texture_compression_dxt5);
- }
+ if (WorkAroundDriverBugs() &&
+ Vendor() == GLVendor::VMware &&
+ Renderer() == GLRenderer::GalliumLlvmpipe)
+ {
+ // The llvmpipe driver that is used on linux try servers appears to have
+ // buggy support for s3tc/dxt1 compressed textures.
+ // See Bug 975824.
+ MarkExtensionUnsupported(EXT_texture_compression_s3tc);
+ MarkExtensionUnsupported(EXT_texture_compression_dxt1);
+ MarkExtensionUnsupported(ANGLE_texture_compression_dxt3);
+ MarkExtensionUnsupported(ANGLE_texture_compression_dxt5);
+ }
#ifdef XP_MACOSX
- // Bug 1009642: On OSX Mavericks (10.9), the driver for Intel HD
- // 3000 appears to be buggy WRT updating sub-images of S3TC
- // textures with glCompressedTexSubImage2D. Works on Intel HD 4000
- // and Intel HD 5000/Iris that I tested.
- if (nsCocoaFeatures::OSXVersionMajor() == 10 &&
- nsCocoaFeatures::OSXVersionMinor() == 9 &&
- Renderer() == GLRenderer::IntelHD3000)
- {
- MarkExtensionUnsupported(EXT_texture_compression_s3tc);
- }
+ // Bug 1009642: On OSX Mavericks (10.9), the driver for Intel HD
+ // 3000 appears to be buggy WRT updating sub-images of S3TC
+ // textures with glCompressedTexSubImage2D. Works on Intel HD 4000
+ // and Intel HD 5000/Iris that I tested.
+ if (WorkAroundDriverBugs() &&
+ nsCocoaFeatures::OSXVersionMajor() == 10 &&
+ nsCocoaFeatures::OSXVersionMinor() == 9 &&
+ Renderer() == GLRenderer::IntelHD3000)
+ {
+ MarkExtensionUnsupported(EXT_texture_compression_s3tc);
+ }
#endif
- }
-
- if (shouldDumpExts) {
- printf_stderr("\nActivated extensions:\n");
-
- for (size_t i = 0; i < mAvailableExtensions.size(); i++) {
- if (!mAvailableExtensions[i])
- continue;
-
- const char* ext = sExtensionNames[i];
- printf_stderr("[%i] %s\n", (uint32_t)i, ext);
- }
- }
}
void
GLContext::PlatformStartup()
{
- RegisterStrongMemoryReporter(new GfxTexturesReporter());
+ RegisterStrongMemoryReporter(new GfxTexturesReporter());
}
// Common code for checking for both GL extensions and GLX extensions.
@@ -1740,6 +1688,66 @@ GLContext::ListHasExtension(const GLubyte *extensions, const char *extension)
return false;
}
+void
+GLContext::DetermineCaps()
+{
+ PixelBufferFormat format = QueryPixelFormat();
+
+ SurfaceCaps caps;
+ caps.color = !!format.red && !!format.green && !!format.blue;
+ caps.bpp16 = caps.color && format.ColorBits() == 16;
+ caps.alpha = !!format.alpha;
+ caps.depth = !!format.depth;
+ caps.stencil = !!format.stencil;
+ caps.antialias = format.samples > 1;
+ caps.preserve = true;
+
+ mCaps = caps;
+}
+
+PixelBufferFormat
+GLContext::QueryPixelFormat()
+{
+ PixelBufferFormat format;
+
+ ScopedBindFramebuffer autoFB(this, 0);
+
+ fGetIntegerv(LOCAL_GL_RED_BITS , &format.red );
+ fGetIntegerv(LOCAL_GL_GREEN_BITS, &format.green);
+ fGetIntegerv(LOCAL_GL_BLUE_BITS , &format.blue );
+ fGetIntegerv(LOCAL_GL_ALPHA_BITS, &format.alpha);
+
+ fGetIntegerv(LOCAL_GL_DEPTH_BITS, &format.depth);
+ fGetIntegerv(LOCAL_GL_STENCIL_BITS, &format.stencil);
+
+ fGetIntegerv(LOCAL_GL_SAMPLES, &format.samples);
+
+ return format;
+}
+
+void
+GLContext::UpdatePixelFormat()
+{
+ PixelBufferFormat format = QueryPixelFormat();
+#ifdef MOZ_GL_DEBUG
+ const SurfaceCaps& caps = Caps();
+ MOZ_ASSERT(!caps.any, "Did you forget to DetermineCaps()?");
+
+ MOZ_ASSERT(caps.color == !!format.red);
+ MOZ_ASSERT(caps.color == !!format.green);
+ MOZ_ASSERT(caps.color == !!format.blue);
+
+ // These we either must have if they're requested, or
+ // we can have if they're not.
+ MOZ_ASSERT(caps.alpha == !!format.alpha || !caps.alpha);
+ MOZ_ASSERT(caps.depth == !!format.depth || !caps.depth);
+ MOZ_ASSERT(caps.stencil == !!format.stencil || !caps.stencil);
+
+ MOZ_ASSERT(caps.antialias == (format.samples > 1));
+#endif
+ mPixelFormat = new PixelBufferFormat(format);
+}
+
GLFormats
GLContext::ChooseGLFormats(const SurfaceCaps& caps) const
{
@@ -2409,13 +2417,6 @@ GLContext::FlushIfHeavyGLCallsSinceLastFlush()
fFlush();
}
-/*static*/ bool
-GLContext::ShouldDumpExts()
-{
- static bool ret = PR_GetEnv("MOZ_GL_DUMP_EXTS");
- return ret;
-}
-
bool
DoesStringMatch(const char* aString, const char *aWantedString)
{
@@ -2443,29 +2444,8 @@ DoesStringMatch(const char* aString, const char *aWantedString)
/*static*/ bool
GLContext::ShouldSpew()
{
- static bool ret = PR_GetEnv("MOZ_GL_SPEW");
- return ret;
-}
-
-void
-SplitByChar(const nsACString& str, const char delim, std::vector* const out)
-{
- uint32_t start = 0;
- while (true) {
- int32_t end = str.FindChar(' ', start);
- if (end == -1)
- break;
-
- uint32_t len = (uint32_t)end - start;
- nsDependentCSubstring substr(str, start, len);
- out->push_back(nsCString(substr));
-
- start = end + 1;
- continue;
- }
-
- nsDependentCSubstring substr(str, start);
- out->push_back(nsCString(substr));
+ static bool spew = PR_GetEnv("MOZ_GL_SPEW");
+ return spew;
}
} /* namespace gl */
diff --git a/gfx/gl/GLContext.h b/gfx/gl/GLContext.h
index cc6d8fcf2a4..9cc3a090634 100644
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -104,7 +104,6 @@ enum class GLFeature {
get_integer_indexed,
get_integer64_indexed,
get_query_object_iv,
- get_string_indexed,
gpu_shader4,
instanced_arrays,
instanced_non_arrays,
@@ -309,6 +308,7 @@ public:
virtual bool IsCurrent() = 0;
protected:
+
bool mInitialized;
bool mIsOffscreen;
bool mIsGlobalSharedContext;
@@ -325,12 +325,9 @@ protected:
GLVendor mVendor;
GLRenderer mRenderer;
- void SetProfileVersion(ContextProfile profile, uint32_t version) {
- MOZ_ASSERT(!mInitialized, "SetProfileVersion can only be called before"
- " initialization!");
- MOZ_ASSERT(profile != ContextProfile::Unknown &&
- profile != ContextProfile::OpenGL,
- "Invalid `profile` for SetProfileVersion");
+ inline void SetProfileVersion(ContextProfile profile, unsigned int version) {
+ MOZ_ASSERT(!mInitialized, "SetProfileVersion can only be called before initialization!");
+ MOZ_ASSERT(profile != ContextProfile::Unknown && profile != ContextProfile::OpenGL, "Invalid `profile` for SetProfileVersion");
MOZ_ASSERT(version >= 100, "Invalid `version` for SetProfileVersion");
mVersion = version;
@@ -460,7 +457,6 @@ public:
return mAvailableExtensions[aKnownExtension];
}
-protected:
void MarkExtensionUnsupported(GLExtensions aKnownExtension) {
mAvailableExtensions[aKnownExtension] = 0;
}
@@ -469,6 +465,42 @@ protected:
mAvailableExtensions[aKnownExtension] = 1;
}
+public:
+ template
+ static void InitializeExtensionsBitSet(std::bitset& extensionsBitset,
+ const char* extStr,
+ const char** extList)
+ {
+ char* exts = ::strdup(extStr);
+
+ if (ShouldSpew())
+ printf_stderr("Extensions: %s\n", exts);
+
+ char* cur = exts;
+ bool done = false;
+ while (!done) {
+ char* space = strchr(cur, ' ');
+ if (space) {
+ *space = '\0';
+ } else {
+ done = true;
+ }
+
+ for (int i = 0; extList[i]; ++i) {
+ if (PL_strcasecmp(cur, extList[i]) == 0) {
+ if (ShouldSpew())
+ printf_stderr("Found extension %s\n", cur);
+ extensionsBitset[i] = true;
+ }
+ }
+
+ cur = space + 1;
+ }
+
+ free(exts);
+ }
+
+protected:
std::bitset mAvailableExtensions;
// -----------------------------------------------------------------------------
@@ -3148,17 +3180,6 @@ public:
AFTER_GL_CALL;
}
-// -----------------------------------------------------------------------------
-// get_string_indexed
-
- const GLubyte* fGetStringi(GLenum name, GLuint index) {
- BEFORE_GL_CALL;
- ASSERT_SYMBOL_PRESENT(fGetStringi);
- const GLubyte* ret = mSymbols.fGetStringi(name, index);
- AFTER_GL_CALL;
- return ret;
- }
-
// -----------------------------------------------------------------------------
// Constructor
protected:
@@ -3427,9 +3448,11 @@ public:
fViewport(0, 0, size.width, size.height);
mCaps = mScreen->mCaps;
- MOZ_ASSERT(!mCaps.any);
+ if (mCaps.any)
+ DetermineCaps();
UpdateGLFormats(mCaps);
+ UpdatePixelFormat();
return true;
}
@@ -3452,8 +3475,10 @@ public:
protected:
SurfaceCaps mCaps;
nsAutoPtr mGLFormats;
+ nsAutoPtr mPixelFormat;
public:
+ void DetermineCaps();
const SurfaceCaps& Caps() const {
return mCaps;
}
@@ -3469,6 +3494,14 @@ public:
return *mGLFormats;
}
+ PixelBufferFormat QueryPixelFormat();
+ void UpdatePixelFormat();
+
+ const PixelBufferFormat& GetPixelFormat() const {
+ MOZ_ASSERT(mPixelFormat);
+ return *mPixelFormat;
+ }
+
bool IsFramebufferComplete(GLuint fb, GLenum* status = nullptr);
// Does not check completeness.
@@ -3508,7 +3541,7 @@ public:
}
bool IsOffscreen() const {
- return mIsOffscreen;
+ return !!mScreen;
}
GLScreenBuffer* Screen() const {
@@ -3663,42 +3696,10 @@ protected:
public:
void FlushIfHeavyGLCallsSinceLastFlush();
static bool ShouldSpew();
- static bool ShouldDumpExts();
};
bool DoesStringMatch(const char* aString, const char *aWantedString);
-void SplitByChar(const nsACString& str, const char delim,
- std::vector* const out);
-
-template
-bool
-MarkBitfieldByString(const nsACString& str, const char* (&markStrList)[N],
- std::bitset* const out_markList)
-{
- for (size_t i = 0; i < N; i++) {
- if (str.Equals(markStrList[i])) {
- (*out_markList)[i] = 1;
- return true;
- }
- }
- return false;
-}
-
-template
-void
-MarkBitfieldByStrings(const std::vector& strList,
- bool dumpStrings, const char* (&markStrList)[N],
- std::bitset* const out_markList)
-{
- for (auto itr = strList.begin(); itr != strList.end(); ++itr) {
- const nsACString& str = *itr;
- const bool wasMarked = MarkBitfieldByString(str, markStrList,
- out_markList);
- if (dumpStrings)
- printf_stderr(" %s%s\n", str.BeginReading(), wasMarked ? "(*)" : "");
- }
-}
} /* namespace gl */
} /* namespace mozilla */
diff --git a/gfx/gl/GLContextCGL.h b/gfx/gl/GLContextCGL.h
index 5da7085450c..9b3c52ddd8e 100644
--- a/gfx/gl/GLContextCGL.h
+++ b/gfx/gl/GLContextCGL.h
@@ -28,8 +28,10 @@ class GLContextCGL : public GLContext
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GLContextCGL, MOZ_OVERRIDE)
- GLContextCGL(const SurfaceCaps& caps, NSOpenGLContext* context,
- bool isOffscreen, ContextProfile profile);
+ GLContextCGL(const SurfaceCaps& caps,
+ GLContext *shareContext,
+ NSOpenGLContext *context,
+ bool isOffscreen = false);
~GLContextCGL();
diff --git a/gfx/gl/GLContextFeatures.cpp b/gfx/gl/GLContextFeatures.cpp
index ed2fa69ec9e..0e47ecbae08 100644
--- a/gfx/gl/GLContextFeatures.cpp
+++ b/gfx/gl/GLContextFeatures.cpp
@@ -274,16 +274,6 @@ static const FeatureInfo sFeatureInfoArr[] = {
* ARB_occlusion_query (added by OpenGL 2.0).
*/
},
- {
- "get_string_indexed",
- GLVersion::GL3,
- GLESVersion::ES3,
- GLContext::Extension_None,
- {
- GLContext::Extensions_End
- }
- // glGetStringi
- },
{
"gpu_shader4",
GLVersion::GL3,
diff --git a/gfx/gl/GLContextProviderCGL.mm b/gfx/gl/GLContextProviderCGL.mm
index a5c3a9baf3e..3492e4ab4ea 100644
--- a/gfx/gl/GLContextProviderCGL.mm
+++ b/gfx/gl/GLContextProviderCGL.mm
@@ -21,14 +21,16 @@ namespace gl {
using namespace mozilla::gfx;
+static bool gUseDoubleBufferedWindows = true;
+
class CGLLibrary
{
public:
CGLLibrary()
- : mInitialized(false)
- , mUseDoubleBufferedWindows(true)
- , mOGLLibrary(nullptr)
- {}
+ : mInitialized(false),
+ mOGLLibrary(nullptr),
+ mPixelFormat(nullptr)
+ { }
bool EnsureInitialized()
{
@@ -44,33 +46,48 @@ public:
}
const char* db = PR_GetEnv("MOZ_CGL_DB");
- if (db) {
- mUseDoubleBufferedWindows = *db != '0';
- }
+ gUseDoubleBufferedWindows = (!db || *db != '0');
mInitialized = true;
return true;
}
- bool UseDoubleBufferedWindows() const {
- MOZ_ASSERT(mInitialized);
- return mUseDoubleBufferedWindows;
- }
+ NSOpenGLPixelFormat *PixelFormat()
+ {
+ if (mPixelFormat == nullptr) {
+ NSOpenGLPixelFormatAttribute attribs[] = {
+ NSOpenGLPFAAccelerated,
+ NSOpenGLPFAAllowOfflineRenderers,
+ NSOpenGLPFADoubleBuffer,
+ 0
+ };
+ if (!gUseDoubleBufferedWindows) {
+ attribs[2] = 0;
+ }
+
+ mPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
+ }
+
+ return mPixelFormat;
+ }
private:
bool mInitialized;
- bool mUseDoubleBufferedWindows;
PRLibrary *mOGLLibrary;
+ NSOpenGLPixelFormat *mPixelFormat;
};
CGLLibrary sCGLLibrary;
-GLContextCGL::GLContextCGL(const SurfaceCaps& caps, NSOpenGLContext* context,
- bool isOffscreen, ContextProfile profile)
- : GLContext(caps, nullptr, isOffscreen)
- , mContext(context)
+GLContextCGL::GLContextCGL(
+ const SurfaceCaps& caps,
+ GLContext *shareContext,
+ NSOpenGLContext *context,
+ bool isOffscreen)
+ : GLContext(caps, shareContext, isOffscreen),
+ mContext(context)
{
- SetProfileVersion(profile, 210);
+ SetProfileVersion(ContextProfile::OpenGLCompatibility, 210);
}
GLContextCGL::~GLContextCGL()
@@ -145,7 +162,7 @@ GLContextCGL::SetupLookupFunction()
bool
GLContextCGL::IsDoubleBuffered() const
{
- return sCGLLibrary.UseDoubleBufferedWindows();
+ return gUseDoubleBufferedWindows;
}
bool
@@ -165,66 +182,26 @@ GLContextCGL::SwapBuffers()
}
+static GLContextCGL *
+GetGlobalContextCGL()
+{
+ return static_cast(GLContextProviderCGL::GetGlobalContext());
+}
+
already_AddRefed
GLContextProviderCGL::CreateWrappingExisting(void*, void*)
{
return nullptr;
}
-static const NSOpenGLPixelFormatAttribute kAttribs_singleBuffered[] = {
- NSOpenGLPFAAccelerated,
- NSOpenGLPFAAllowOfflineRenderers,
- 0
-};
-
-static const NSOpenGLPixelFormatAttribute kAttribs_doubleBuffered[] = {
- NSOpenGLPFAAccelerated,
- NSOpenGLPFAAllowOfflineRenderers,
- NSOpenGLPFADoubleBuffer,
- 0
-};
-
-static const NSOpenGLPixelFormatAttribute kAttribs_offscreen[] = {
- NSOpenGLPFAPixelBuffer,
- 0
-};
-
-static const NSOpenGLPixelFormatAttribute kAttribs_offscreen_coreProfile[] = {
- NSOpenGLPFAAccelerated,
- NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
- 0
-};
-
-static NSOpenGLContext*
-CreateWithFormat(const NSOpenGLPixelFormatAttribute* attribs)
-{
- NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc]
- initWithAttributes:attribs];
- if (!format)
- return nullptr;
-
- NSOpenGLContext* context = [[NSOpenGLContext alloc] initWithFormat:format
- shareContext:nullptr];
-
- [format release];
-
- return context;
-}
-
already_AddRefed
GLContextProviderCGL::CreateForWindow(nsIWidget *aWidget)
{
- if (!sCGLLibrary.EnsureInitialized()) {
- return nullptr;
- }
+ GLContextCGL *shareContext = GetGlobalContextCGL();
- const NSOpenGLPixelFormatAttribute* attribs;
- if (sCGLLibrary.UseDoubleBufferedWindows()) {
- attribs = kAttribs_doubleBuffered;
- } else {
- attribs = kAttribs_singleBuffered;
- }
- NSOpenGLContext* context = CreateWithFormat(attribs);
+ NSOpenGLContext *context = [[NSOpenGLContext alloc]
+ initWithFormat:sCGLLibrary.PixelFormat()
+ shareContext:(shareContext ? shareContext->mContext : NULL)];
if (!context) {
return nullptr;
}
@@ -234,13 +211,10 @@ GLContextProviderCGL::CreateForWindow(nsIWidget *aWidget)
[context setValues:&opaque forParameter:NSOpenGLCPSurfaceOpacity];
SurfaceCaps caps = SurfaceCaps::ForRGBA();
- ContextProfile profile = ContextProfile::OpenGLCompatibility;
- nsRefPtr glContext = new GLContextCGL(caps, context, false,
- profile);
-
+ nsRefPtr glContext = new GLContextCGL(caps,
+ shareContext,
+ context);
if (!glContext->Init()) {
- glContext = nullptr;
- [context release];
return nullptr;
}
@@ -248,54 +222,49 @@ GLContextProviderCGL::CreateForWindow(nsIWidget *aWidget)
}
static already_AddRefed
-CreateOffscreenFBOContext(bool requireCompatProfile)
+CreateOffscreenFBOContext(bool aShare = true)
{
if (!sCGLLibrary.EnsureInitialized()) {
return nullptr;
}
- ContextProfile profile;
- NSOpenGLContext* context = nullptr;
+ GLContextCGL *shareContext = aShare ? GetGlobalContextCGL() : nullptr;
+ if (aShare && !shareContext) {
+ // if there is no share context, then we can't use FBOs.
+ return nullptr;
+ }
- if (!requireCompatProfile) {
- profile = ContextProfile::OpenGLCore;
- context = CreateWithFormat(kAttribs_offscreen_coreProfile);
- }
- if (!context) {
- profile = ContextProfile::OpenGLCompatibility;
- context = CreateWithFormat(kAttribs_offscreen);
- }
+ NSOpenGLContext *context = [[NSOpenGLContext alloc]
+ initWithFormat:sCGLLibrary.PixelFormat()
+ shareContext:shareContext ? shareContext->GetNSOpenGLContext() : NULL];
if (!context) {
return nullptr;
}
SurfaceCaps dummyCaps = SurfaceCaps::Any();
- nsRefPtr glContext = new GLContextCGL(dummyCaps, context,
- true, profile);
+ nsRefPtr glContext = new GLContextCGL(dummyCaps, shareContext, context, true);
return glContext.forget();
}
already_AddRefed
-GLContextProviderCGL::CreateHeadless(bool requireCompatProfile)
+GLContextProviderCGL::CreateHeadless()
{
- nsRefPtr gl;
- gl = CreateOffscreenFBOContext(requireCompatProfile);
- if (!gl)
+ nsRefPtr glContext = CreateOffscreenFBOContext();
+ if (!glContext)
return nullptr;
- if (!gl->Init())
+ if (!glContext->Init())
return nullptr;
- return gl.forget();
+ return glContext.forget();
}
already_AddRefed
GLContextProviderCGL::CreateOffscreen(const gfxIntSize& size,
- const SurfaceCaps& caps,
- bool requireCompatProfile)
+ const SurfaceCaps& caps)
{
- nsRefPtr glContext = CreateHeadless(requireCompatProfile);
+ nsRefPtr glContext = CreateHeadless();
if (!glContext->InitOffscreen(ToIntSize(size), caps))
return nullptr;
@@ -330,7 +299,7 @@ GLContextProviderCGL::GetGlobalContext()
void
GLContextProviderCGL::Shutdown()
{
- gGlobalContext = nullptr;
+ gGlobalContext = nullptr;
}
} /* namespace gl */
diff --git a/gfx/gl/GLContextProviderEGL.cpp b/gfx/gl/GLContextProviderEGL.cpp
index b946167fa66..12c2068091d 100644
--- a/gfx/gl/GLContextProviderEGL.cpp
+++ b/gfx/gl/GLContextProviderEGL.cpp
@@ -878,7 +878,7 @@ GLContextEGL::CreateEGLPixmapOffscreenContext(const gfxIntSize& size)
}
already_AddRefed
-GLContextProviderEGL::CreateHeadless(bool)
+GLContextProviderEGL::CreateHeadless()
{
if (!sEGLLibrary.EnsureInitialized()) {
return nullptr;
@@ -897,10 +897,9 @@ GLContextProviderEGL::CreateHeadless(bool)
// often without the ability to texture from them directly.
already_AddRefed
GLContextProviderEGL::CreateOffscreen(const gfxIntSize& size,
- const SurfaceCaps& caps,
- bool requireCompatProfile)
+ const SurfaceCaps& caps)
{
- nsRefPtr glContext = CreateHeadless(requireCompatProfile);
+ nsRefPtr glContext = CreateHeadless();
if (!glContext)
return nullptr;
diff --git a/gfx/gl/GLContextProviderGLX.cpp b/gfx/gl/GLContextProviderGLX.cpp
index f95ae85dafa..bdbc984370d 100644
--- a/gfx/gl/GLContextProviderGLX.cpp
+++ b/gfx/gl/GLContextProviderGLX.cpp
@@ -1215,7 +1215,7 @@ DONE_CREATING_PIXMAP:
}
already_AddRefed
-GLContextProviderGLX::CreateHeadless(bool)
+GLContextProviderGLX::CreateHeadless()
{
gfxIntSize dummySize = gfxIntSize(16, 16);
nsRefPtr glContext = CreateOffscreenPixmapContext(dummySize);
@@ -1227,10 +1227,9 @@ GLContextProviderGLX::CreateHeadless(bool)
already_AddRefed
GLContextProviderGLX::CreateOffscreen(const gfxIntSize& size,
- const SurfaceCaps& caps,
- bool requireCompatProfile)
+ const SurfaceCaps& caps)
{
- nsRefPtr glContext = CreateHeadless(requireCompatProfile);
+ nsRefPtr glContext = CreateHeadless();
if (!glContext)
return nullptr;
diff --git a/gfx/gl/GLContextProviderImpl.h b/gfx/gl/GLContextProviderImpl.h
index 9e87170c823..6efc65de064 100644
--- a/gfx/gl/GLContextProviderImpl.h
+++ b/gfx/gl/GLContextProviderImpl.h
@@ -58,12 +58,11 @@ public:
*/
static already_AddRefed
CreateOffscreen(const gfxIntSize& size,
- const SurfaceCaps& caps,
- bool requireCompatProfile);
+ const SurfaceCaps& caps);
// Just create a context. We'll add offscreen stuff ourselves.
static already_AddRefed
- CreateHeadless(bool requireCompatProfile);
+ CreateHeadless();
/**
* Create wrapping Gecko GLContext for external gl context.
diff --git a/gfx/gl/GLContextProviderNull.cpp b/gfx/gl/GLContextProviderNull.cpp
index 231c75be5f3..61732a6e6b6 100644
--- a/gfx/gl/GLContextProviderNull.cpp
+++ b/gfx/gl/GLContextProviderNull.cpp
@@ -22,14 +22,13 @@ GLContextProviderNull::CreateWrappingExisting(void*, void*)
already_AddRefed
GLContextProviderNull::CreateOffscreen(const gfxIntSize&,
- const SurfaceCaps&,
- bool)
+ const SurfaceCaps&)
{
return nullptr;
}
already_AddRefed
-GLContextProviderNull::CreateHeadless(bool)
+GLContextProviderNull::CreateHeadless()
{
return nullptr;
}
diff --git a/gfx/gl/GLContextProviderWGL.cpp b/gfx/gl/GLContextProviderWGL.cpp
index bf605c057e9..a8c2124d678 100644
--- a/gfx/gl/GLContextProviderWGL.cpp
+++ b/gfx/gl/GLContextProviderWGL.cpp
@@ -607,7 +607,7 @@ CreateWindowOffscreenContext()
}
already_AddRefed
-GLContextProviderWGL::CreateHeadless(bool)
+GLContextProviderWGL::CreateHeadless()
{
if (!sWGLLib.EnsureInitialized()) {
return nullptr;
@@ -641,10 +641,9 @@ GLContextProviderWGL::CreateHeadless(bool)
already_AddRefed
GLContextProviderWGL::CreateOffscreen(const gfxIntSize& size,
- const SurfaceCaps& caps,
- bool requireCompatProfile)
+ const SurfaceCaps& caps)
{
- nsRefPtr glContext = CreateHeadless(requireCompatProfile);
+ nsRefPtr glContext = CreateHeadless();
if (!glContext)
return nullptr;
diff --git a/gfx/gl/GLContextSymbols.h b/gfx/gl/GLContextSymbols.h
index 91ff5ac71dc..3904beac173 100644
--- a/gfx/gl/GLContextSymbols.h
+++ b/gfx/gl/GLContextSymbols.h
@@ -666,10 +666,6 @@ struct GLContextSymbols
GLsizei width, GLsizei height, GLsizei depth,
GLenum format, GLsizei imageSize, const GLvoid* data);
PFNGLCOMPRESSEDTEXSUBIMAGE3D fCompressedTexSubImage3D;
-
- // get_string_indexed
- typedef const GLubyte* (GLAPIENTRY * pfnGLGetStringiT)(GLenum name, GLuint index);
- pfnGLGetStringiT fGetStringi;
};
}
diff --git a/gfx/gl/GLContextTypes.cpp b/gfx/gl/GLContextTypes.cpp
index 2cca59dc96a..b11c99098d2 100644
--- a/gfx/gl/GLContextTypes.cpp
+++ b/gfx/gl/GLContextTypes.cpp
@@ -12,3 +12,8 @@ GLFormats::GLFormats()
{
std::memset(this, 0, sizeof(GLFormats));
}
+
+PixelBufferFormat::PixelBufferFormat()
+{
+ std::memset(this, 0, sizeof(PixelBufferFormat));
+}
diff --git a/gfx/gl/GLContextTypes.h b/gfx/gl/GLContextTypes.h
index 979790bb1e5..f21cc11cf06 100644
--- a/gfx/gl/GLContextTypes.h
+++ b/gfx/gl/GLContextTypes.h
@@ -43,6 +43,19 @@ struct GLFormats
GLsizei samples;
};
+struct PixelBufferFormat
+{
+ // Constructs a zeroed object:
+ PixelBufferFormat();
+
+ int red, green, blue;
+ int alpha;
+ int depth, stencil;
+ int samples;
+
+ int ColorBits() const { return red + green + blue; }
+};
+
} /* namespace gl */
} /* namespace mozilla */
diff --git a/gfx/gl/GLLibraryEGL.cpp b/gfx/gl/GLLibraryEGL.cpp
index 40cee8d0c98..a07b3e79f3d 100644
--- a/gfx/gl/GLLibraryEGL.cpp
+++ b/gfx/gl/GLLibraryEGL.cpp
@@ -35,7 +35,8 @@ static const char *sEGLExtensionNames[] = {
"EGL_EXT_create_context_robustness",
"EGL_KHR_image",
"EGL_KHR_fence_sync",
- "EGL_ANDROID_native_fence_sync"
+ "EGL_ANDROID_native_fence_sync",
+ nullptr
};
#if defined(ANDROID)
@@ -239,8 +240,8 @@ GLLibraryEGL::EnsureInitialized()
};
// Do not warn about the failure to load this - see bug 1092191
- GLLibraryLoader::LoadSymbols(mEGLLibrary, &optionalSymbols[0], nullptr, nullptr,
- false);
+ GLLibraryLoader::LoadSymbols(mEGLLibrary, &optionalSymbols[0],
+ nullptr, nullptr, false);
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 18
MOZ_RELEASE_ASSERT(mSymbols.fQueryStringImplementationANDROID,
@@ -420,24 +421,15 @@ GLLibraryEGL::EnsureInitialized()
void
GLLibraryEGL::InitExtensions()
{
- std::vector driverExtensionList;
+ const char *extensions = (const char*)fQueryString(mEGLDisplay, LOCAL_EGL_EXTENSIONS);
- const char* rawExts = (const char*)fQueryString(mEGLDisplay, LOCAL_EGL_EXTENSIONS);
- if (rawExts) {
- nsDependentCString exts(rawExts);
- SplitByChar(exts, ' ', &driverExtensionList);
- } else {
+ if (!extensions) {
NS_WARNING("Failed to load EGL extension list!");
+ return;
}
- const bool shouldDumpExts = GLContext::ShouldDumpExts();
- if (shouldDumpExts) {
- printf_stderr("%i EGL driver extensions: (*: recognized)\n",
- (uint32_t)driverExtensionList.size());
- }
-
- MarkBitfieldByStrings(driverExtensionList, shouldDumpExts, sEGLExtensionNames,
- &mAvailableExtensions);
+ GLContext::InitializeExtensionsBitSet(mAvailableExtensions, extensions,
+ sEGLExtensionNames);
}
void
diff --git a/gfx/gl/GLLibraryEGL.h b/gfx/gl/GLLibraryEGL.h
index 4e055344c8f..1d175a217ef 100644
--- a/gfx/gl/GLLibraryEGL.h
+++ b/gfx/gl/GLLibraryEGL.h
@@ -15,7 +15,6 @@
#include "GeckoProfiler.h"
#include
-#include
#if defined(XP_WIN)
diff --git a/gfx/layers/GLImages.cpp b/gfx/layers/GLImages.cpp
index 7525eefd40f..66fa218df96 100644
--- a/gfx/layers/GLImages.cpp
+++ b/gfx/layers/GLImages.cpp
@@ -39,7 +39,7 @@ GLImage::GetAsSourceSurface()
MOZ_ASSERT(NS_IsMainThread(), "Should be on the main thread");
if (!sSnapshotContext) {
- sSnapshotContext = GLContextProvider::CreateHeadless(false);
+ sSnapshotContext = GLContextProvider::CreateHeadless();
if (!sSnapshotContext) {
NS_WARNING("Failed to create snapshot GLContext");
return nullptr;
diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp
index 4aab23384e8..bc78494c155 100644
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -124,11 +124,8 @@ CompositorOGL::CreateContext()
SurfaceCaps caps = SurfaceCaps::ForRGB();
caps.preserve = false;
caps.bpp16 = gfxPlatform::GetPlatform()->GetOffscreenFormat() == gfxImageFormat::RGB16_565;
-
- bool requireCompatProfile = true;
context = GLContextProvider::CreateOffscreen(gfxIntSize(mSurfaceSize.width,
- mSurfaceSize.height),
- caps, requireCompatProfile);
+ mSurfaceSize.height), caps);
}
if (!context)
diff --git a/gfx/tests/gtest/TestCompositor.cpp b/gfx/tests/gtest/TestCompositor.cpp
index 273fc5516a4..70ff21d8a3a 100644
--- a/gfx/tests/gtest/TestCompositor.cpp
+++ b/gfx/tests/gtest/TestCompositor.cpp
@@ -45,7 +45,7 @@ public:
caps.preserve = false;
caps.bpp16 = false;
nsRefPtr context = GLContextProvider::CreateOffscreen(
- gfxIntSize(gCompWidth, gCompHeight), caps, true);
+ gfxIntSize(gCompWidth, gCompHeight), caps);
return context.forget().take();
}
return nullptr;
diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp
index 1394387fceb..2e271cf3f52 100644
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -1099,9 +1099,8 @@ gfxPlatform::GetSkiaGLGlue()
* FIXME: This should be stored in TLS or something, since there needs to be one for each thread using it. As it
* stands, this only works on the main thread.
*/
- bool requireCompatProfile = true;
- nsRefPtr glContext;
- glContext = mozilla::gl::GLContextProvider::CreateHeadless(requireCompatProfile);
+ mozilla::gl::SurfaceCaps caps = mozilla::gl::SurfaceCaps::ForRGBA();
+ nsRefPtr glContext = mozilla::gl::GLContextProvider::CreateOffscreen(gfxIntSize(16, 16), caps);
if (!glContext) {
printf_stderr("Failed to create GLContext for SkiaGL!\n");
return nullptr;
diff --git a/mobile/android/base/db/BrowserDatabaseHelper.java b/mobile/android/base/db/BrowserDatabaseHelper.java
index f9dcb19e25e..ae4a06a9cd8 100644
--- a/mobile/android/base/db/BrowserDatabaseHelper.java
+++ b/mobile/android/base/db/BrowserDatabaseHelper.java
@@ -24,6 +24,7 @@ import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.os.Build;
@@ -767,12 +768,18 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
private void upgradeDatabaseFrom21to22(SQLiteDatabase db) {
debug("Adding CONTENT_STATUS column to reading list table.");
- db.execSQL("ALTER TABLE " + TABLE_READING_LIST +
- " ADD COLUMN " + ReadingListItems.CONTENT_STATUS +
- " TINYINT DEFAULT " + ReadingListItems.STATUS_UNFETCHED);
+ try {
+ db.execSQL("ALTER TABLE " + TABLE_READING_LIST +
+ " ADD COLUMN " + ReadingListItems.CONTENT_STATUS +
+ " TINYINT DEFAULT " + ReadingListItems.STATUS_UNFETCHED);
- db.execSQL("CREATE INDEX reading_list_content_status ON " + TABLE_READING_LIST + "("
- + ReadingListItems.CONTENT_STATUS + ")");
+ db.execSQL("CREATE INDEX reading_list_content_status ON " + TABLE_READING_LIST + "("
+ + ReadingListItems.CONTENT_STATUS + ")");
+ } catch (SQLiteException e) {
+ // We're betting that an error here means that the table already has the column,
+ // so we're failing due to the duplicate column name.
+ Log.e(LOGTAG, "Error upgrading database from 21 to 22", e);
+ }
}
private void createV19CombinedView(SQLiteDatabase db) {
@@ -840,7 +847,11 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
break;
case 22:
- upgradeDatabaseFrom21to22(db);
+ if (oldVersion <= 17) {
+ // We just created the right table in 17to18. Do nothing here.
+ } else {
+ upgradeDatabaseFrom21to22(db);
+ }
break;
}
}
diff --git a/mobile/android/components/MobileComponents.manifest b/mobile/android/components/MobileComponents.manifest
index f0c95ddbc36..9e33376a597 100644
--- a/mobile/android/components/MobileComponents.manifest
+++ b/mobile/android/components/MobileComponents.manifest
@@ -30,11 +30,6 @@ component {ef0f7a87-c1ee-45a8-8d67-26f586e46a4b} DirectoryProvider.js
contract @mozilla.org/browser/directory-provider;1 {ef0f7a87-c1ee-45a8-8d67-26f586e46a4b}
category xpcom-directory-providers browser-directory-provider @mozilla.org/browser/directory-provider;1
-# Sidebar.js
-component {22117140-9c6e-11d3-aaf1-00805f8a4905} Sidebar.js
-contract @mozilla.org/sidebar;1 {22117140-9c6e-11d3-aaf1-00805f8a4905}
-category wakeup-request Sidebar @mozilla.org/sidebar;1,nsISidebarExternal,getService,Sidebar:AddSearchProvider
-
# SessionStore.js
component {8c1f07d6-cba3-4226-a315-8bd43d67d032} SessionStore.js
contract @mozilla.org/browser/sessionstore;1 {8c1f07d6-cba3-4226-a315-8bd43d67d032}
diff --git a/mobile/android/components/Sidebar.js b/mobile/android/components/Sidebar.js
deleted file mode 100644
index 30e83c41ac9..00000000000
--- a/mobile/android/components/Sidebar.js
+++ /dev/null
@@ -1,130 +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/. */
-
-const Ci = Components.interfaces;
-const Cc = Components.classes;
-const Cu = Components.utils;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-const SIDEBAR_CID = Components.ID("{22117140-9c6e-11d3-aaf1-00805f8a4905}");
-const SIDEBAR_CONTRACTID = "@mozilla.org/sidebar;1";
-
-function Sidebar() {
- // Depending on if we are in the parent or child, prepare to remote
- // certain calls
- var appInfo = Cc["@mozilla.org/xre/app-info;1"];
- if (!appInfo || appInfo.getService(Ci.nsIXULRuntime).processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT) {
- // Parent process
-
- this.inContentProcess = false;
-
- // Used for wakeups service. FIXME: clean up with bug 593407
- this.wrappedJSObject = this;
-
- // Setup listener for child messages. We don't need to call
- // addMessageListener as the wakeup service will do that for us.
- this.receiveMessage = function(aMessage) {
- switch (aMessage.name) {
- case "Sidebar:AddSearchProvider":
- this.AddSearchProvider(aMessage.json.descriptionURL);
- }
- };
- } else {
- // Child process
-
- this.inContentProcess = true;
- this.messageManager = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsISyncMessageSender);
- }
-}
-
-Sidebar.prototype = {
- // =========================== utility code ===========================
- _validateSearchEngine: function validateSearchEngine(engineURL, iconURL) {
- try {
- // Make sure we're using HTTP, HTTPS, or FTP.
- if (! /^(https?|ftp):\/\//i.test(engineURL))
- throw "Unsupported search engine URL";
-
- // Make sure we're using HTTP, HTTPS, or FTP and refering to a
- // .gif/.jpg/.jpeg/.png/.ico file for the icon.
- if (iconURL &&
- ! /^(https?|ftp):\/\/.+\.(gif|jpg|jpeg|png|ico)$/i.test(iconURL))
- throw "Unsupported search icon URL.";
- } catch(ex) {
- Cu.reportError("Invalid argument passed to window.sidebar.addSearchEngine: " + ex);
-
- var searchBundle = Services.strings.createBundle("chrome://global/locale/search/search.properties");
- var brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
- var brandName = brandBundle.GetStringFromName("brandShortName");
- var title = searchBundle.GetStringFromName("error_invalid_engine_title");
- var msg = searchBundle.formatStringFromName("error_invalid_engine_msg",
- [brandName], 1);
- Services.prompt.alert(null, title, msg);
- return false;
- }
-
- return true;
- },
-
- // The suggestedTitle and suggestedCategory parameters are ignored, but remain
- // for backward compatibility.
- addSearchEngine: function addSearchEngine(engineURL, iconURL, suggestedTitle,
- suggestedCategory) {
- if (!this._validateSearchEngine(engineURL, iconURL))
- return;
-
- // File extension for Sherlock search plugin description files
- const SHERLOCK_FILE_EXT_REGEXP = /\.src$/i;
-
- // OpenSearch files will likely be far more common than Sherlock files, and
- // have less consistent suffixes, so we assume that ".src" is a Sherlock
- // (text) file, and anything else is OpenSearch (XML).
- var dataType;
- if (SHERLOCK_FILE_EXT_REGEXP.test(engineURL))
- dataType = Ci.nsISearchEngine.DATA_TEXT;
- else
- dataType = Ci.nsISearchEngine.DATA_XML;
-
- Services.search.addEngine(engineURL, dataType, iconURL, true);
- },
-
- // This function exists to implement window.external.AddSearchProvider(),
- // to match other browsers' APIs. The capitalization, although nonstandard here,
- // is therefore important.
- AddSearchProvider: function AddSearchProvider(aDescriptionURL) {
- if (!this._validateSearchEngine(aDescriptionURL, ""))
- return;
-
- if (this.inContentProcess) {
- this.messageManager.sendAsyncMessage("Sidebar:AddSearchProvider",
- { descriptionURL: aDescriptionURL });
- return;
- }
-
- const typeXML = Ci.nsISearchEngine.DATA_XML;
- Services.search.addEngine(aDescriptionURL, typeXML, "", true);
- },
-
- // This function exists to implement window.external.IsSearchProviderInstalled(),
- // for compatibility with other browsers. It will return an integer value
- // indicating whether the given engine is installed for the current user.
- // However, it is currently stubbed out due to security/privacy concerns
- // stemming from difficulties in determining what domain issued the request.
- // See bug 340604 and
- // http://msdn.microsoft.com/en-us/library/aa342526%28VS.85%29.aspx .
- // XXX Implement this!
- IsSearchProviderInstalled: function IsSearchProviderInstalled(aSearchURL) {
- return 0;
- },
-
- // =========================== nsISupports ===========================
- QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
-
- // XPCOMUtils stuff
- classID: SIDEBAR_CID,
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([Sidebar]);
diff --git a/mobile/android/components/moz.build b/mobile/android/components/moz.build
index 91a1e9aac83..cbc614b461a 100644
--- a/mobile/android/components/moz.build
+++ b/mobile/android/components/moz.build
@@ -26,7 +26,6 @@ EXTRA_COMPONENTS += [
'NSSDialogService.js',
'PromptService.js',
'SessionStore.js',
- 'Sidebar.js',
'SiteSpecificUserAgent.js',
'Snippets.js',
'TabSource.js',
diff --git a/testing/docker/builder/VERSION b/testing/docker/builder/VERSION
index 53a75d67355..0d91a54c7d4 100644
--- a/testing/docker/builder/VERSION
+++ b/testing/docker/builder/VERSION
@@ -1 +1 @@
-0.2.6
+0.3.0
diff --git a/testing/taskcluster/mach_commands.py b/testing/taskcluster/mach_commands.py
index 7b46c9943d7..56c4b20f543 100644
--- a/testing/taskcluster/mach_commands.py
+++ b/testing/taskcluster/mach_commands.py
@@ -105,6 +105,8 @@ class DecisionTask(object):
@CommandArgument('--revision',
required=True,
help='Revision for this project')
+ @CommandArgument('--revision-hash',
+ help='Treeherder revision hash')
@CommandArgument('--comment',
required=True,
help='Commit message for this revision')
@@ -121,6 +123,7 @@ class DecisionTask(object):
'comment': params['comment'],
'url': params['url'],
'revision': params['revision'],
+ 'revision_hash': params.get('revision_hash', ''),
'owner': params['owner'],
'as_slugid': SlugidJar(),
'from_now': json_time_from_now,
diff --git a/testing/taskcluster/tasks/branches/base_job_flags.yml b/testing/taskcluster/tasks/branches/base_job_flags.yml
index 58136214304..d67875c34a3 100644
--- a/testing/taskcluster/tasks/branches/base_job_flags.yml
+++ b/testing/taskcluster/tasks/branches/base_job_flags.yml
@@ -11,6 +11,8 @@ flags:
- linux64-mulet # Firefox desktop - b2g gecko linux 64 bit
- macosx64_gecko # b2g desktop osx 64 bit
- win32_gecko # b2g desktop win 32 bit
+ - flame-kk # b2g flame kitkat
+ - flame-kk-eng # b2g flame eng build
tests:
- cppunit
diff --git a/testing/taskcluster/tasks/builds/b2g_emulator_ics_debug.yml b/testing/taskcluster/tasks/builds/b2g_emulator_ics_debug.yml
index 8750c7987c8..8c2d8326d2a 100644
--- a/testing/taskcluster/tasks/builds/b2g_emulator_ics_debug.yml
+++ b/testing/taskcluster/tasks/builds/b2g_emulator_ics_debug.yml
@@ -1,6 +1,7 @@
$inherits:
from: 'tasks/builds/b2g_emulator_base.yml'
task:
+ workerType: emulator-ics-debug
scopes:
- 'docker-worker:cache:build-emulator-ics-debug'
metadata:
diff --git a/testing/taskcluster/tasks/builds/b2g_emulator_ics_opt.yml b/testing/taskcluster/tasks/builds/b2g_emulator_ics_opt.yml
index ebeb9567902..6e0a57f296c 100644
--- a/testing/taskcluster/tasks/builds/b2g_emulator_ics_opt.yml
+++ b/testing/taskcluster/tasks/builds/b2g_emulator_ics_opt.yml
@@ -1,6 +1,7 @@
$inherits:
from: 'tasks/builds/b2g_emulator_base.yml'
task:
+ workerType: emulator-ics
scopes:
- 'docker-worker:cache:build-emulator-ics-opt'
metadata:
diff --git a/testing/taskcluster/tasks/builds/b2g_emulator_jb_debug.yml b/testing/taskcluster/tasks/builds/b2g_emulator_jb_debug.yml
index cfcbbc0dba7..0158a64df82 100644
--- a/testing/taskcluster/tasks/builds/b2g_emulator_jb_debug.yml
+++ b/testing/taskcluster/tasks/builds/b2g_emulator_jb_debug.yml
@@ -1,6 +1,7 @@
$inherits:
from: 'tasks/builds/b2g_emulator_base.yml'
task:
+ workerType: emulator-jb-debug
scopes:
- 'docker-worker:cache:build-emulator-jb-debug'
metadata:
diff --git a/testing/taskcluster/tasks/builds/b2g_emulator_jb_opt.yml b/testing/taskcluster/tasks/builds/b2g_emulator_jb_opt.yml
index a396c458788..44db1ff35d8 100644
--- a/testing/taskcluster/tasks/builds/b2g_emulator_jb_opt.yml
+++ b/testing/taskcluster/tasks/builds/b2g_emulator_jb_opt.yml
@@ -1,6 +1,7 @@
$inherits:
from: 'tasks/builds/b2g_emulator_base.yml'
task:
+ workerType: emulator-jb
scopes:
- 'docker-worker:cache:build-emulator-jb-opt'
metadata:
diff --git a/testing/taskcluster/tasks/builds/b2g_emulator_kk_debug.yml b/testing/taskcluster/tasks/builds/b2g_emulator_kk_debug.yml
index c826e436719..0d412ea0cdc 100644
--- a/testing/taskcluster/tasks/builds/b2g_emulator_kk_debug.yml
+++ b/testing/taskcluster/tasks/builds/b2g_emulator_kk_debug.yml
@@ -1,7 +1,7 @@
$inherits:
from: 'tasks/builds/b2g_emulator_base.yml'
task:
- workerType: b2gbuild-emulator-kk
+ workerType: emulator-kk-debug
scopes:
- 'docker-worker:cache:build-emulator-kk-debug'
metadata:
diff --git a/testing/taskcluster/tasks/builds/b2g_emulator_kk_opt.yml b/testing/taskcluster/tasks/builds/b2g_emulator_kk_opt.yml
index 67e05364d22..060e8e3c3cd 100644
--- a/testing/taskcluster/tasks/builds/b2g_emulator_kk_opt.yml
+++ b/testing/taskcluster/tasks/builds/b2g_emulator_kk_opt.yml
@@ -1,7 +1,7 @@
$inherits:
from: 'tasks/builds/b2g_emulator_base.yml'
task:
- workerType: b2gbuild-emulator-kk
+ workerType: emulator-kk
scopes:
- 'docker-worker:cache:build-emulator-kk-opt'
metadata:
diff --git a/testing/taskcluster/tasks/decision/branch.yml b/testing/taskcluster/tasks/decision/branch.yml
index 50a53b30e2b..48455c8a0e2 100644
--- a/testing/taskcluster/tasks/decision/branch.yml
+++ b/testing/taskcluster/tasks/decision/branch.yml
@@ -7,27 +7,11 @@ metadata:
source: "{{source}}"
scopes:
- - "docker-worker:image:quay.io/mozilla/decision:*"
- - "queue:define-task:aws-provisioner/gecko-decision"
- - "queue:create-task:aws-provisioner/gecko-decision"
- - "docker-worker:cache:tc-vcs-public-sources"
- - "docker-worker:cache:build-emulator-jb-opt"
- - "docker-worker:cache:build-mulet-linux-objects"
- - "docker-worker:cache:build-emulator-ics-opt"
- - "queue:define-task:aws-provisioner/b2gtest"
- - "queue:create-task:aws-provisioner/b2gtest"
- - "docker-worker:image:quay.io/mozilla/builder:*"
- - "docker-worker:cache:tooltool-cache"
- - "queue:define-task:aws-provisioner/b2gbuild"
- - "queue:create-task:aws-provisioner/b2gbuild"
- - "docker-worker:cache:build-emulator-kk-debug"
- - "docker-worker:cache:build-b2g-desktop-objects"
- - "docker-worker:cache:build-emulator-kk-opt"
- - "docker-worker:cache:build-emulator-jb-debug"
- - "docker-worker:cache:tc-vcs"
- - "docker-worker:cache:sources-gecko"
- - "docker-worker:cache:sources-gaia"
- - "docker-worker:cache:build-emulator-ics-debug"
+ # Note the below scopes are insecure however these get overriden on the server
+ # side to whatever scopes are set by mozilla-taskcluster.
+ - queue:*
+ - docker-worker:*
+ - scheduler:*
tasks:
- taskId: '{{#as_slugid}}decision task{{/as_slugid}}'
task:
@@ -46,7 +30,7 @@ tasks:
scopes:
- "docker-worker:cache:tc-vcs-public-sources"
- - "docker-worker:image:quay.io/mozilla/decision:0.0.3"
+ - "docker-worker:image:quay.io/mozilla/builder:0.3.0"
payload:
env:
@@ -63,7 +47,7 @@ tasks:
# Note: This task is built server side without the context or tooling that
# exist in tree so we must hard code the version
- image: 'quay.io/mozilla/decision:0.0.3'
+ image: 'quay.io/mozilla/builder:0.3.0'
# Virtually no network or other potentially risky operations happen as part
# of the task timeout aside from the initial clone. We intentionally have
@@ -75,11 +59,12 @@ tasks:
- /bin/bash
- -cx
- >
- source $(which entrypoint) &&
+ source ./bin/decision.sh &&
./mach taskcluster-graph
--message='{{comment}}'
--project='{{project}}'
--owner='{{owner}}'
+ --revision-hash='{{revision_hash}}'
--extend-graph > /home/worker/graph.json
graphs:
- /home/worker/graph.json
diff --git a/testing/taskcluster/tasks/test.yml b/testing/taskcluster/tasks/test.yml
index 2a76e94753e..2bc4cf0617c 100644
--- a/testing/taskcluster/tasks/test.yml
+++ b/testing/taskcluster/tasks/test.yml
@@ -5,7 +5,7 @@ task:
metadata:
source: http://todo.com/soon
owner: {{owner}}
- workerType: test-c4-2xlarge
+ workerType: b2gtest
provisionerId: aws-provisioner
schedulerId: task-graph-scheduler
diff --git a/toolkit/components/processsingleton/MainProcessSingleton.js b/toolkit/components/processsingleton/MainProcessSingleton.js
index 689edd55972..c72cfebd643 100644
--- a/toolkit/components/processsingleton/MainProcessSingleton.js
+++ b/toolkit/components/processsingleton/MainProcessSingleton.js
@@ -4,9 +4,7 @@
"use strict";
-const Cu = Components.utils;
-const Ci = Components.interfaces;
-const Cc = Components.classes;
+const { utils: Cu, interfaces: Ci, classes: Cc, results: Cr } = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
@@ -19,18 +17,67 @@ XPCOMUtils.defineLazyServiceGetter(this, "globalmm",
"@mozilla.org/globalmessagemanager;1",
"nsIMessageBroadcaster");
+XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
+ "resource://gre/modules/NetUtil.jsm");
+
function MainProcessSingleton() {}
MainProcessSingleton.prototype = {
classID: Components.ID("{0636a680-45cb-11e4-916c-0800200c9a66}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
Ci.nsISupportsWeakReference]),
- receiveMessage: function(message) {
+ logConsoleMessage: function(message) {
let logMsg = message.data;
logMsg.wrappedJSObject = logMsg;
Services.obs.notifyObservers(logMsg, "console-api-log-event", null);
},
+ // Called when a webpage calls either window.external.AddSearchProvider or
+ // window.sidebar.addSearchEngine
+ addSearchEngine: function({ target: browser, data: { pageURL, engineURL, iconURL, type } }) {
+ pageURL = NetUtil.newURI(pageURL);
+ engineURL = NetUtil.newURI(engineURL, null, pageURL);
+
+ if (iconURL) {
+ iconURL = NetUtil.newURI(iconURL, null, pageURL);
+ }
+ else {
+ let tabbrowser = browser.getTabBrowser();
+ if (browser.mIconURL && (!tabbrowser || tabbrowser.shouldLoadFavIcon(pageURL)))
+ iconURL = NetUtil.newURI(browser.mIconURL);
+ }
+
+ try {
+ // Make sure the URLs are HTTP, HTTPS, or FTP.
+ let isWeb = ["https", "http", "ftp"];
+
+ if (isWeb.indexOf(engineURL.scheme) < 0)
+ throw "Unsupported search engine URL: " + engineURL;
+
+ if (iconURL && isWeb.indexOf(iconURL.scheme) < 0)
+ throw "Unsupported search icon URL: " + iconURL;
+ }
+ catch(ex) {
+ Cu.reportError("Invalid argument passed to window.sidebar.addSearchEngine: " + ex);
+
+ var searchBundle = Services.strings.createBundle("chrome://global/locale/search/search.properties");
+ var brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
+ var brandName = brandBundle.GetStringFromName("brandShortName");
+ var title = searchBundle.GetStringFromName("error_invalid_engine_title");
+ var msg = searchBundle.formatStringFromName("error_invalid_engine_msg",
+ [brandName], 1);
+ Services.ww.getNewPrompter(browser.ownerDocument.defaultView).alert(title, msg);
+ return;
+ }
+
+ Services.search.init(function(status) {
+ if (status != Cr.NS_OK)
+ return;
+
+ Services.search.addEngine(engineURL.spec, type, iconURL ? iconURL.spec : null, true);
+ })
+ },
+
observe: function(subject, topic, data) {
switch (topic) {
case "app-startup": {
@@ -39,12 +86,14 @@ MainProcessSingleton.prototype = {
// Load this script early so that console.* is initialized
// before other frame scripts.
globalmm.loadFrameScript("chrome://global/content/browser-content.js", true);
- ppmm.addMessageListener("Console:Log", this);
+ ppmm.addMessageListener("Console:Log", this.logConsoleMessage);
+ globalmm.addMessageListener("Search:AddEngine", this.addSearchEngine);
break;
}
case "xpcom-shutdown":
- ppmm.removeMessageListener("Console:Log", this);
+ ppmm.removeMessageListener("Console:Log", this.logConsoleMessage);
+ globalmm.removeMessageListener("Search:AddEngine", this.addSearchEngine);
break;
}
},
diff --git a/toolkit/components/search/moz.build b/toolkit/components/search/moz.build
index ef9fa946cfd..999e3272a14 100644
--- a/toolkit/components/search/moz.build
+++ b/toolkit/components/search/moz.build
@@ -8,6 +8,7 @@ XPCSHELL_TESTS_MANIFESTS += ['tests/xpcshell/xpcshell.ini']
EXTRA_COMPONENTS += [
'nsSearchSuggestions.js',
+ 'nsSidebar.js',
'toolkitsearch.manifest',
]
diff --git a/toolkit/components/search/nsSidebar.js b/toolkit/components/search/nsSidebar.js
new file mode 100644
index 00000000000..b2a47cf3213
--- /dev/null
+++ b/toolkit/components/search/nsSidebar.js
@@ -0,0 +1,63 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 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/. */
+
+const { interfaces: Ci, utils: Cu } = Components;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+// File extension for Sherlock search plugin description files
+const SHERLOCK_FILE_EXT_REGEXP = /\.src$/i;
+
+function nsSidebar() {
+}
+
+nsSidebar.prototype = {
+ init: function(window) {
+ this.window = window;
+ this.mm = window.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDocShell)
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIContentFrameMessageManager);
+ },
+
+ // The suggestedTitle and suggestedCategory parameters are ignored, but remain
+ // for backward compatibility.
+ addSearchEngine: function(engineURL, iconURL, suggestedTitle, suggestedCategory) {
+ let dataType = SHERLOCK_FILE_EXT_REGEXP.test(engineURL) ?
+ Ci.nsISearchEngine.DATA_TEXT :
+ Ci.nsISearchEngine.DATA_XML;
+
+ this.mm.sendAsyncMessage("Search:AddEngine", {
+ pageURL: this.window.document.documentURIObject.spec,
+ engineURL,
+ type: dataType,
+ iconURL
+ });
+ },
+
+ // This function exists largely to implement window.external.AddSearchProvider(),
+ // to match other browsers' APIs. The capitalization, although nonstandard here,
+ // is therefore important.
+ AddSearchProvider: function(engineURL) {
+ this.mm.sendAsyncMessage("Search:AddEngine", {
+ pageURL: this.window.document.documentURIObject.spec,
+ engineURL,
+ type: Ci.nsISearchEngine.DATA_XML
+ });
+ },
+
+ // This function exists to implement window.external.IsSearchProviderInstalled(),
+ // for compatibility with other browsers. The function has been deprecated
+ // and so will not be implemented.
+ IsSearchProviderInstalled: function(engineURL) {
+ return 0;
+ },
+
+ classID: Components.ID("{22117140-9c6e-11d3-aaf1-00805f8a4905}"),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
+ Ci.nsIDOMGlobalPropertyInitializer])
+}
+
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([nsSidebar]);
diff --git a/toolkit/components/search/toolkitsearch.manifest b/toolkit/components/search/toolkitsearch.manifest
index 359e5551faf..e481a7a5be3 100644
--- a/toolkit/components/search/toolkitsearch.manifest
+++ b/toolkit/components/search/toolkitsearch.manifest
@@ -4,3 +4,5 @@ contract @mozilla.org/browser/search-service;1 {7319788a-fe93-4db3-9f39-818cf08f
category update-timer nsSearchService @mozilla.org/browser/search-service;1,getService,search-engine-update-timer,browser.search.update.interval,21600
component {aa892eb4-ffbf-477d-9f9a-06c995ae9f27} nsSearchSuggestions.js
contract @mozilla.org/autocomplete/search;1?name=search-autocomplete {aa892eb4-ffbf-477d-9f9a-06c995ae9f27}
+component {22117140-9c6e-11d3-aaf1-00805f8a4905} nsSidebar.js
+contract @mozilla.org/sidebar;1 {22117140-9c6e-11d3-aaf1-00805f8a4905}
diff --git a/toolkit/devtools/client/connection-manager.js b/toolkit/devtools/client/connection-manager.js
index 2593b8490df..1f57c475672 100644
--- a/toolkit/devtools/client/connection-manager.js
+++ b/toolkit/devtools/client/connection-manager.js
@@ -249,7 +249,9 @@ Connection.prototype = {
this.status == Connection.Status.CONNECTING) {
this.log("disconnecting");
this._setStatus(Connection.Status.DISCONNECTING);
- this._client.close();
+ if (this._client) {
+ this._client.close();
+ }
}
},
diff --git a/widget/android/GfxInfo.cpp b/widget/android/GfxInfo.cpp
index 95bd0d409cd..4ab9da311ed 100644
--- a/widget/android/GfxInfo.cpp
+++ b/widget/android/GfxInfo.cpp
@@ -72,8 +72,8 @@ public:
}
nsRefPtr gl;
- bool requireCompatProfile = true;
- gl = gl::GLContextProvider::CreateHeadless(requireCompatProfile);
+ gl = gl::GLContextProvider::CreateOffscreen(gfxIntSize(16, 16),
+ gl::SurfaceCaps::ForRGB());
if (!gl) {
// Setting mReady to true here means that we won't retry. Everything will