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;
+ + + +
+
&wifi_auth_token_request;
+
+      &wifi_auth_yes_scanner;
+    
+ + + 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