mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Merge inbound to central, a=merge
This commit is contained in:
commit
d602abb016
@ -27,7 +27,7 @@
|
||||
#include "nsISimpleEnumerator.h"
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/Snprintf.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
#include "nsXPCOMStrings.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsIPersistentProperties2.h"
|
||||
@ -436,7 +436,7 @@ GetUniqueMaiAtkTypeName(uint16_t interfacesBits)
|
||||
static gchar namePrefix[] = "MaiAtkType"; /* size = 10 */
|
||||
static gchar name[MAI_ATK_TYPE_NAME_LEN + 1];
|
||||
|
||||
snprintf_literal(name, "%s%x", namePrefix, interfacesBits);
|
||||
SprintfLiteral(name, "%s%x", namePrefix, interfacesBits);
|
||||
name[MAI_ATK_TYPE_NAME_LEN] = '\0';
|
||||
|
||||
return name;
|
||||
|
@ -1070,9 +1070,6 @@ pref("dom.webnotifications.serviceworker.enabled", true);
|
||||
// Retain at most 10 processes' layers buffers
|
||||
pref("layers.compositor-lru-size", 10);
|
||||
|
||||
// Enable Cardboard VR on mobile, assuming VR at all is enabled
|
||||
pref("dom.vr.cardboard.enabled", true);
|
||||
|
||||
// In B2G by deafult any AudioChannelAgent is muted when created.
|
||||
pref("dom.audiochannel.mutedByDefault", true);
|
||||
|
||||
|
@ -78,8 +78,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
.text-link,
|
||||
.text-link:focus {
|
||||
description > .text-link,
|
||||
description > .text-link:focus {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
@ -274,17 +274,17 @@ extensions.registerSchemaAPI("browserAction", (extension, context) => {
|
||||
}).api(),
|
||||
|
||||
enable: function(tabId) {
|
||||
let tab = tabId !== null ? TabManager.getTab(tabId) : null;
|
||||
let tab = tabId !== null ? TabManager.getTab(tabId, context) : null;
|
||||
BrowserAction.for(extension).setProperty(tab, "enabled", true);
|
||||
},
|
||||
|
||||
disable: function(tabId) {
|
||||
let tab = tabId !== null ? TabManager.getTab(tabId) : null;
|
||||
let tab = tabId !== null ? TabManager.getTab(tabId, context) : null;
|
||||
BrowserAction.for(extension).setProperty(tab, "enabled", false);
|
||||
},
|
||||
|
||||
setTitle: function(details) {
|
||||
let tab = details.tabId !== null ? TabManager.getTab(details.tabId) : null;
|
||||
let tab = details.tabId !== null ? TabManager.getTab(details.tabId, context) : null;
|
||||
|
||||
let title = details.title;
|
||||
// Clear the tab-specific title when given a null string.
|
||||
@ -295,31 +295,36 @@ extensions.registerSchemaAPI("browserAction", (extension, context) => {
|
||||
},
|
||||
|
||||
getTitle: function(details) {
|
||||
let tab = details.tabId !== null ? TabManager.getTab(details.tabId) : null;
|
||||
let tab = details.tabId !== null ? TabManager.getTab(details.tabId, context) : null;
|
||||
|
||||
let title = BrowserAction.for(extension).getProperty(tab, "title");
|
||||
return Promise.resolve(title);
|
||||
},
|
||||
|
||||
setIcon: function(details) {
|
||||
let tab = details.tabId !== null ? TabManager.getTab(details.tabId) : null;
|
||||
let tab = details.tabId !== null ? TabManager.getTab(details.tabId, context) : null;
|
||||
|
||||
let icon = IconDetails.normalize(details, extension, context);
|
||||
BrowserAction.for(extension).setProperty(tab, "icon", icon);
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
||||
setBadgeText: function(details) {
|
||||
let tab = details.tabId !== null ? TabManager.getTab(details.tabId) : null;
|
||||
let tab = details.tabId !== null ? TabManager.getTab(details.tabId, context) : null;
|
||||
|
||||
BrowserAction.for(extension).setProperty(tab, "badgeText", details.text);
|
||||
},
|
||||
|
||||
getBadgeText: function(details) {
|
||||
let tab = details.tabId !== null ? TabManager.getTab(details.tabId) : null;
|
||||
let tab = details.tabId !== null ? TabManager.getTab(details.tabId, context) : null;
|
||||
|
||||
let text = BrowserAction.for(extension).getProperty(tab, "badgeText");
|
||||
return Promise.resolve(text);
|
||||
},
|
||||
|
||||
setPopup: function(details) {
|
||||
let tab = details.tabId !== null ? TabManager.getTab(details.tabId) : null;
|
||||
let tab = details.tabId !== null ? TabManager.getTab(details.tabId, context) : null;
|
||||
|
||||
// Note: Chrome resolves arguments to setIcon relative to the calling
|
||||
// context, but resolves arguments to setPopup relative to the extension
|
||||
// root.
|
||||
@ -330,13 +335,14 @@ extensions.registerSchemaAPI("browserAction", (extension, context) => {
|
||||
},
|
||||
|
||||
getPopup: function(details) {
|
||||
let tab = details.tabId !== null ? TabManager.getTab(details.tabId) : null;
|
||||
let tab = details.tabId !== null ? TabManager.getTab(details.tabId, context) : null;
|
||||
|
||||
let popup = BrowserAction.for(extension).getProperty(tab, "popup");
|
||||
return Promise.resolve(popup);
|
||||
},
|
||||
|
||||
setBadgeBackgroundColor: function(details) {
|
||||
let tab = details.tabId !== null ? TabManager.getTab(details.tabId) : null;
|
||||
let tab = details.tabId !== null ? TabManager.getTab(details.tabId, context) : null;
|
||||
let color = details.color;
|
||||
if (!Array.isArray(color)) {
|
||||
let col = colorUtils.colorToRGBA(color);
|
||||
@ -346,7 +352,8 @@ extensions.registerSchemaAPI("browserAction", (extension, context) => {
|
||||
},
|
||||
|
||||
getBadgeBackgroundColor: function(details, callback) {
|
||||
let tab = details.tabId !== null ? TabManager.getTab(details.tabId) : null;
|
||||
let tab = details.tabId !== null ? TabManager.getTab(details.tabId, context) : null;
|
||||
|
||||
let color = BrowserAction.for(extension).getProperty(tab, "badgeBackgroundColor");
|
||||
return Promise.resolve(color || [0xd9, 0, 0, 255]);
|
||||
},
|
||||
|
@ -233,39 +233,42 @@ extensions.registerSchemaAPI("pageAction", (extension, context) => {
|
||||
}).api(),
|
||||
|
||||
show(tabId) {
|
||||
let tab = TabManager.getTab(tabId);
|
||||
let tab = TabManager.getTab(tabId, context);
|
||||
PageAction.for(extension).setProperty(tab, "show", true);
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
||||
hide(tabId) {
|
||||
let tab = TabManager.getTab(tabId);
|
||||
let tab = TabManager.getTab(tabId, context);
|
||||
PageAction.for(extension).setProperty(tab, "show", false);
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
||||
setTitle(details) {
|
||||
let tab = TabManager.getTab(details.tabId);
|
||||
let tab = TabManager.getTab(details.tabId, context);
|
||||
|
||||
// Clear the tab-specific title when given a null string.
|
||||
PageAction.for(extension).setProperty(tab, "title", details.title || null);
|
||||
},
|
||||
|
||||
getTitle(details) {
|
||||
let tab = TabManager.getTab(details.tabId);
|
||||
let tab = TabManager.getTab(details.tabId, context);
|
||||
|
||||
let title = PageAction.for(extension).getProperty(tab, "title");
|
||||
return Promise.resolve(title);
|
||||
},
|
||||
|
||||
setIcon(details) {
|
||||
let tab = TabManager.getTab(details.tabId);
|
||||
let tab = TabManager.getTab(details.tabId, context);
|
||||
|
||||
let icon = IconDetails.normalize(details, extension, context);
|
||||
PageAction.for(extension).setProperty(tab, "icon", icon);
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
||||
setPopup(details) {
|
||||
let tab = TabManager.getTab(details.tabId);
|
||||
let tab = TabManager.getTab(details.tabId, context);
|
||||
|
||||
// Note: Chrome resolves arguments to setIcon relative to the calling
|
||||
// context, but resolves arguments to setPopup relative to the extension
|
||||
// root.
|
||||
@ -276,7 +279,8 @@ extensions.registerSchemaAPI("pageAction", (extension, context) => {
|
||||
},
|
||||
|
||||
getPopup(details) {
|
||||
let tab = TabManager.getTab(details.tabId);
|
||||
let tab = TabManager.getTab(details.tabId, context);
|
||||
|
||||
let popup = PageAction.for(extension).getProperty(tab, "popup");
|
||||
return Promise.resolve(popup);
|
||||
},
|
||||
|
@ -37,7 +37,8 @@ function getSender(context, target, sender) {
|
||||
// The message came from an ExtensionContext. In that case, it should
|
||||
// include a tabId property (which is filled in by the page-open
|
||||
// listener below).
|
||||
sender.tab = TabManager.convert(context.extension, TabManager.getTab(sender.tabId));
|
||||
sender.tab = TabManager.convert(context.extension,
|
||||
TabManager.getTab(sender.tabId, context));
|
||||
delete sender.tabId;
|
||||
}
|
||||
}
|
||||
@ -551,7 +552,7 @@ extensions.registerSchemaAPI("tabs", (extension, context) => {
|
||||
}
|
||||
|
||||
for (let tabId of tabs) {
|
||||
let tab = TabManager.getTab(tabId);
|
||||
let tab = TabManager.getTab(tabId, context);
|
||||
tab.ownerGlobal.gBrowser.removeTab(tab);
|
||||
}
|
||||
|
||||
@ -559,11 +560,7 @@ extensions.registerSchemaAPI("tabs", (extension, context) => {
|
||||
},
|
||||
|
||||
update: function(tabId, updateProperties) {
|
||||
let tab = tabId !== null ? TabManager.getTab(tabId) : TabManager.activeTab;
|
||||
|
||||
if (!tab) {
|
||||
return Promise.reject({message: `No tab found with tabId: ${tabId}`});
|
||||
}
|
||||
let tab = tabId !== null ? TabManager.getTab(tabId, context) : TabManager.activeTab;
|
||||
|
||||
let tabbrowser = tab.ownerGlobal.gBrowser;
|
||||
|
||||
@ -602,7 +599,8 @@ extensions.registerSchemaAPI("tabs", (extension, context) => {
|
||||
},
|
||||
|
||||
reload: function(tabId, reloadProperties) {
|
||||
let tab = tabId !== null ? TabManager.getTab(tabId) : TabManager.activeTab;
|
||||
let tab = tabId !== null ? TabManager.getTab(tabId, context) : TabManager.activeTab;
|
||||
|
||||
let flags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
|
||||
if (reloadProperties && reloadProperties.bypassCache) {
|
||||
flags |= Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE;
|
||||
@ -613,14 +611,15 @@ extensions.registerSchemaAPI("tabs", (extension, context) => {
|
||||
},
|
||||
|
||||
get: function(tabId) {
|
||||
let tab = TabManager.getTab(tabId);
|
||||
let tab = TabManager.getTab(tabId, context);
|
||||
|
||||
return Promise.resolve(TabManager.convert(extension, tab));
|
||||
},
|
||||
|
||||
getCurrent() {
|
||||
let tab;
|
||||
if (context.tabId) {
|
||||
tab = TabManager.convert(extension, TabManager.getTab(context.tabId));
|
||||
tab = TabManager.convert(extension, TabManager.getTab(context.tabId, context));
|
||||
}
|
||||
return Promise.resolve(tab);
|
||||
},
|
||||
@ -736,10 +735,7 @@ extensions.registerSchemaAPI("tabs", (extension, context) => {
|
||||
},
|
||||
|
||||
detectLanguage: function(tabId) {
|
||||
let tab = tabId !== null ? TabManager.getTab(tabId) : TabManager.activeTab;
|
||||
if (!tab) {
|
||||
return Promise.reject({message: `Invalid tab ID: ${tabId}`});
|
||||
}
|
||||
let tab = tabId !== null ? TabManager.getTab(tabId, context) : TabManager.activeTab;
|
||||
|
||||
let browser = tab.linkedBrowser;
|
||||
let recipient = {innerWindowID: browser.innerWindowID};
|
||||
@ -750,7 +746,7 @@ extensions.registerSchemaAPI("tabs", (extension, context) => {
|
||||
|
||||
// Used to executeScript, insertCSS and removeCSS.
|
||||
_execute: function(tabId, details, kind, method) {
|
||||
let tab = tabId !== null ? TabManager.getTab(tabId) : TabManager.activeTab;
|
||||
let tab = tabId !== null ? TabManager.getTab(tabId, context) : TabManager.activeTab;
|
||||
let mm = tab.linkedBrowser.messageManager;
|
||||
|
||||
let options = {
|
||||
@ -821,7 +817,7 @@ extensions.registerSchemaAPI("tabs", (extension, context) => {
|
||||
},
|
||||
|
||||
connect: function(tabId, connectInfo) {
|
||||
let tab = TabManager.getTab(tabId);
|
||||
let tab = TabManager.getTab(tabId, context);
|
||||
let mm = tab.linkedBrowser.messageManager;
|
||||
|
||||
let name = "";
|
||||
@ -836,7 +832,7 @@ extensions.registerSchemaAPI("tabs", (extension, context) => {
|
||||
},
|
||||
|
||||
sendMessage: function(tabId, message, options, responseCallback) {
|
||||
let tab = TabManager.getTab(tabId);
|
||||
let tab = TabManager.getTab(tabId, context, null);
|
||||
if (!tab) {
|
||||
// ignore sendMessage to non existent tab id
|
||||
return;
|
||||
@ -875,13 +871,8 @@ extensions.registerSchemaAPI("tabs", (extension, context) => {
|
||||
*/
|
||||
let indexMap = new Map();
|
||||
|
||||
for (let tabId of tabIds) {
|
||||
let tab = TabManager.getTab(tabId);
|
||||
// Ignore invalid tab ids.
|
||||
if (!tab) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let tabs = tabIds.map(tabId => TabManager.getTab(tabId, context));
|
||||
for (let tab of tabs) {
|
||||
// If the window is not specified, use the window from the tab.
|
||||
let window = destinationWindow || tab.ownerGlobal;
|
||||
let gBrowser = window.gBrowser;
|
||||
@ -919,10 +910,7 @@ extensions.registerSchemaAPI("tabs", (extension, context) => {
|
||||
},
|
||||
|
||||
duplicate: function(tabId) {
|
||||
let tab = TabManager.getTab(tabId);
|
||||
if (!tab) {
|
||||
return Promise.reject({message: `Invalid tab ID: ${tabId}`});
|
||||
}
|
||||
let tab = TabManager.getTab(tabId, context);
|
||||
|
||||
let gBrowser = tab.ownerGlobal.gBrowser;
|
||||
let newTab = gBrowser.duplicateTab(tab);
|
||||
@ -952,7 +940,7 @@ extensions.registerSchemaAPI("tabs", (extension, context) => {
|
||||
},
|
||||
|
||||
getZoom(tabId) {
|
||||
let tab = tabId ? TabManager.getTab(tabId) : TabManager.activeTab;
|
||||
let tab = tabId ? TabManager.getTab(tabId, context) : TabManager.activeTab;
|
||||
|
||||
let {ZoomManager} = tab.ownerGlobal;
|
||||
let zoom = ZoomManager.getZoomForBrowser(tab.linkedBrowser);
|
||||
@ -961,7 +949,7 @@ extensions.registerSchemaAPI("tabs", (extension, context) => {
|
||||
},
|
||||
|
||||
setZoom(tabId, zoom) {
|
||||
let tab = tabId ? TabManager.getTab(tabId) : TabManager.activeTab;
|
||||
let tab = tabId ? TabManager.getTab(tabId, context) : TabManager.activeTab;
|
||||
|
||||
let {FullZoom, ZoomManager} = tab.ownerGlobal;
|
||||
|
||||
@ -980,7 +968,7 @@ extensions.registerSchemaAPI("tabs", (extension, context) => {
|
||||
},
|
||||
|
||||
_getZoomSettings(tabId) {
|
||||
let tab = tabId ? TabManager.getTab(tabId) : TabManager.activeTab;
|
||||
let tab = tabId ? TabManager.getTab(tabId, context) : TabManager.activeTab;
|
||||
|
||||
let {FullZoom} = tab.ownerGlobal;
|
||||
|
||||
@ -996,7 +984,7 @@ extensions.registerSchemaAPI("tabs", (extension, context) => {
|
||||
},
|
||||
|
||||
setZoomSettings(tabId, settings) {
|
||||
let tab = tabId ? TabManager.getTab(tabId) : TabManager.activeTab;
|
||||
let tab = tabId ? TabManager.getTab(tabId, context) : TabManager.activeTab;
|
||||
|
||||
let currentSettings = this._getZoomSettings(tab.id);
|
||||
|
||||
|
@ -681,7 +681,21 @@ global.TabManager = {
|
||||
return -1;
|
||||
},
|
||||
|
||||
getTab(tabId) {
|
||||
/**
|
||||
* Returns the XUL <tab> element associated with the given tab ID. If no tab
|
||||
* with the given ID exists, and no default value is provided, an error is
|
||||
* raised, belonging to the scope of the given context.
|
||||
*
|
||||
* @param {integer} tabId
|
||||
* The ID of the tab to retrieve.
|
||||
* @param {ExtensionContext} context
|
||||
* The context of the caller.
|
||||
* @param {*} default_
|
||||
* The value to return if no tab exists with the given ID.
|
||||
* @returns {Element<tab>}
|
||||
* A XUL <tab> element.
|
||||
*/
|
||||
getTab(tabId, context, default_ = undefined) {
|
||||
// FIXME: Speed this up without leaking memory somehow.
|
||||
for (let window of WindowListManager.browserWindows()) {
|
||||
if (!window.gBrowser) {
|
||||
@ -693,7 +707,10 @@ global.TabManager = {
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
if (default_ !== undefined) {
|
||||
return default_;
|
||||
}
|
||||
throw new context.cloneScope.Error(`Invalid tab ID: ${tabId}`);
|
||||
},
|
||||
|
||||
get activeTab() {
|
||||
|
@ -93,10 +93,7 @@ extensions.registerSchemaAPI("windows", (extension, context) => {
|
||||
return Promise.reject({message: "`tabId` may not be used in conjunction with `url`"});
|
||||
}
|
||||
|
||||
let tab = TabManager.getTab(createData.tabId);
|
||||
if (tab == null) {
|
||||
return Promise.reject({message: `Invalid tab ID: ${createData.tabId}`});
|
||||
}
|
||||
let tab = TabManager.getTab(createData.tabId, context);
|
||||
|
||||
// Private browsing tabs can only be moved to private browsing
|
||||
// windows.
|
||||
|
@ -44,6 +44,35 @@ function* runTests(options) {
|
||||
let tabs = [];
|
||||
let tests = getTests(tabs, expectDefaults);
|
||||
|
||||
{
|
||||
let tabId = 0xdeadbeef;
|
||||
let calls = [
|
||||
() => browser.browserAction.enable(tabId),
|
||||
() => browser.browserAction.disable(tabId),
|
||||
() => browser.browserAction.setTitle({tabId, title: "foo"}),
|
||||
() => browser.browserAction.setIcon({tabId, path: "foo.png"}),
|
||||
() => browser.browserAction.setPopup({tabId, popup: "foo.html"}),
|
||||
() => browser.browserAction.setBadgeText({tabId, text: "foo"}),
|
||||
() => browser.browserAction.setBadgeBackgroundColor({tabId, color: [0xff, 0, 0, 0xff]}),
|
||||
];
|
||||
|
||||
for (let call of calls) {
|
||||
let checkError = e => {
|
||||
browser.test.assertTrue(e.message.includes(`Invalid tab ID: ${tabId}`),
|
||||
`Expected invalid tab ID error, got ${e}`);
|
||||
};
|
||||
try {
|
||||
call().then(() => {
|
||||
browser.test.fail(`Expected call to fail: ${call}`);
|
||||
}, e => {
|
||||
checkError(e);
|
||||
});
|
||||
} catch (e) {
|
||||
checkError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Runs the next test in the `tests` array, checks the results,
|
||||
// and passes control back to the outer test scope.
|
||||
function nextTest() {
|
||||
|
@ -11,7 +11,7 @@ add_task(function* testWebNavigationGetNonExistentTab() {
|
||||
browser.webNavigation.getAllFrames({tabId: 0}).then(() => {
|
||||
browser.test.fail("getAllFrames Promise should be rejected on error");
|
||||
}, (error) => {
|
||||
browser.test.assertEq("No tab found with tabId: 0", error.message,
|
||||
browser.test.assertEq("Invalid tab ID: 0", error.message,
|
||||
"getAllFrames rejected Promise should pass the expected error");
|
||||
}),
|
||||
// There is no "tabId = 0" because the id assigned by TabManager (defined in ext-utils.js)
|
||||
@ -19,7 +19,7 @@ add_task(function* testWebNavigationGetNonExistentTab() {
|
||||
browser.webNavigation.getFrame({tabId: 0, frameId: 15, processId: 20}).then(() => {
|
||||
browser.test.fail("getFrame Promise should be rejected on error");
|
||||
}, (error) => {
|
||||
browser.test.assertEq("No tab found with tabId: 0", error.message,
|
||||
browser.test.assertEq("Invalid tab ID: 0", error.message,
|
||||
"getFrame rejected Promise should pass the expected error");
|
||||
}),
|
||||
];
|
||||
|
@ -331,7 +331,7 @@ nsFeedSniffer::OnStartRequest(nsIRequest* request, nsISupports* context)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsresult
|
||||
nsFeedSniffer::AppendSegmentToString(nsIInputStream* inputStream,
|
||||
void* closure,
|
||||
const char* rawSegment,
|
||||
|
@ -18,12 +18,12 @@ public:
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
|
||||
static NS_METHOD AppendSegmentToString(nsIInputStream* inputStream,
|
||||
void* closure,
|
||||
const char* rawSegment,
|
||||
uint32_t toOffset,
|
||||
uint32_t count,
|
||||
uint32_t* writeCount);
|
||||
static nsresult AppendSegmentToString(nsIInputStream* inputStream,
|
||||
void* closure,
|
||||
const char* rawSegment,
|
||||
uint32_t toOffset,
|
||||
uint32_t count,
|
||||
uint32_t* writeCount);
|
||||
|
||||
protected:
|
||||
~nsFeedSniffer() {}
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "nsIImageLoadingContent.h"
|
||||
#include "imgIRequest.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "mozilla/Snprintf.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
#if defined(MOZ_WIDGET_GTK)
|
||||
#include "nsIImageToPixbuf.h"
|
||||
#endif
|
||||
|
@ -20,6 +20,7 @@ const MAX_UNIQUE_VISITED_DOMAINS = 100;
|
||||
|
||||
// Observed topic names.
|
||||
const WINDOWS_RESTORED_TOPIC = "sessionstore-windows-restored";
|
||||
const TAB_RESTORING_TOPIC = "SSTabRestoring";
|
||||
const TELEMETRY_SUBSESSIONSPLIT_TOPIC = "internal-telemetry-after-subsession-split";
|
||||
const DOMWINDOW_OPENED_TOPIC = "domwindowopened";
|
||||
|
||||
@ -48,6 +49,21 @@ function getOpenTabsAndWinsCounts() {
|
||||
let URICountListener = {
|
||||
// A set containing the visited domains, see bug 1271310.
|
||||
_domainSet: new Set(),
|
||||
// A map to keep track of the URIs loaded from the restored tabs.
|
||||
_restoredURIsMap: new WeakMap(),
|
||||
|
||||
isValidURI(uri) {
|
||||
// Only consider http(s) schemas.
|
||||
return uri.schemeIs("http") || uri.schemeIs("https");
|
||||
},
|
||||
|
||||
addRestoredURI(browser, uri) {
|
||||
if (!this.isValidURI(uri)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._restoredURIsMap.set(browser, uri.spec);
|
||||
},
|
||||
|
||||
onLocationChange(browser, webProgress, request, uri, flags) {
|
||||
// Don't count this URI if it's an error page.
|
||||
@ -60,8 +76,25 @@ let URICountListener = {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only consider http(s) schemas.
|
||||
if (!uri.schemeIs("http") && !uri.schemeIs("https")) {
|
||||
if (!this.isValidURI(uri)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The SessionStore sets the URI of a tab first, firing onLocationChange the
|
||||
// first time, then manages content loading using its scheduler. Once content
|
||||
// loads, we will hit onLocationChange again.
|
||||
// We can catch the first case by checking for null requests: be advised that
|
||||
// this can also happen when navigating page fragments, so account for it.
|
||||
if (!request &&
|
||||
!(flags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the URI we're loading is in the _restoredURIsMap, then it comes from a
|
||||
// restored tab. If so, let's skip it and remove it from the map as we want to
|
||||
// count page refreshes.
|
||||
if (this._restoredURIsMap.get(browser) === uri.spec) {
|
||||
this._restoredURIsMap.delete(browser);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -146,6 +179,13 @@ let BrowserUsageTelemetry = {
|
||||
case "unload":
|
||||
this._unregisterWindow(event.target);
|
||||
break;
|
||||
case TAB_RESTORING_TOPIC:
|
||||
// We're restoring a new tab from a previous or crashed session.
|
||||
// We don't want to track the URIs from these tabs, so let
|
||||
// |URICountListener| know about them.
|
||||
let browser = event.target.linkedBrowser;
|
||||
URICountListener.addRestoredURI(browser, browser.currentURI);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
@ -182,6 +222,7 @@ let BrowserUsageTelemetry = {
|
||||
if (PrivateBrowsingUtils.isWindowPrivate(win)) {
|
||||
return;
|
||||
}
|
||||
win.gBrowser.tabContainer.addEventListener(TAB_RESTORING_TOPIC, this);
|
||||
win.gBrowser.addTabsProgressListener(URICountListener);
|
||||
},
|
||||
|
||||
@ -196,6 +237,7 @@ let BrowserUsageTelemetry = {
|
||||
if (PrivateBrowsingUtils.isWindowPrivate(win.defaultView)) {
|
||||
return;
|
||||
}
|
||||
win.defaultView.gBrowser.tabContainer.removeEventListener(TAB_RESTORING_TOPIC, this);
|
||||
win.defaultView.gBrowser.removeTabsProgressListener(URICountListener);
|
||||
},
|
||||
|
||||
|
@ -44,6 +44,15 @@ function browserLocationChanged(browser) {
|
||||
});
|
||||
}
|
||||
|
||||
function promiseBrowserStateRestored() {
|
||||
return new Promise(resolve => {
|
||||
Services.obs.addObserver(function observer(aSubject, aTopic) {
|
||||
Services.obs.removeObserver(observer, "sessionstore-browser-state-restored");
|
||||
resolve();
|
||||
}, "sessionstore-browser-state-restored", false);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* An helper that checks the value of a scalar if it's expected to be > 0,
|
||||
* otherwise makes sure that the scalar it's not reported.
|
||||
@ -266,3 +275,50 @@ add_task(function* test_privateMode() {
|
||||
// Clean up.
|
||||
yield BrowserTestUtils.closeWindow(privateWin);
|
||||
});
|
||||
|
||||
add_task(function* test_sessionRestore() {
|
||||
const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
|
||||
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false);
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
|
||||
});
|
||||
|
||||
// Let's reset the counts.
|
||||
Services.telemetry.clearScalars();
|
||||
|
||||
// The first window will be put into the already open window and the second
|
||||
// window will be opened with _openWindowWithState, which is the source of the problem.
|
||||
const state = {
|
||||
windows: [
|
||||
{
|
||||
tabs: [
|
||||
{ entries: [{ url: "http://example.org" }], extData: { "uniq": 3785 } }
|
||||
],
|
||||
selected: 1
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
// Save the current session.
|
||||
let SessionStore =
|
||||
Cu.import("resource:///modules/sessionstore/SessionStore.jsm", {}).SessionStore;
|
||||
let backupState = SessionStore.getBrowserState();
|
||||
|
||||
// Load the custom state and wait for SSTabRestored, as we want to make sure
|
||||
// that the URI counting code was hit.
|
||||
let tabRestored = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "SSTabRestored");
|
||||
SessionStore.setBrowserState(JSON.stringify(state));
|
||||
yield tabRestored;
|
||||
|
||||
// Check that the URI is not recorded.
|
||||
const scalars =
|
||||
Services.telemetry.snapshotScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN);
|
||||
|
||||
ok(!(TOTAL_URI_COUNT in scalars), "We should not track URIs from restored sessions.");
|
||||
ok(!(UNIQUE_DOMAINS_COUNT in scalars), "We should not track unique domains from restored sessions.");
|
||||
|
||||
// Restore the original session and cleanup.
|
||||
let sessionRestored = promiseBrowserStateRestored();
|
||||
SessionStore.setBrowserState(JSON.stringify(state));
|
||||
yield sessionRestored;
|
||||
});
|
||||
|
@ -8,23 +8,47 @@ package org.mozilla.gecko.annotationProcessors;
|
||||
* Object holding annotation data. Used by GeneratableElementIterator.
|
||||
*/
|
||||
public class AnnotationInfo {
|
||||
public final String wrapperName;
|
||||
public final boolean isMultithreaded;
|
||||
public final boolean noThrow;
|
||||
public final boolean narrowChars;
|
||||
public final boolean catchException;
|
||||
public enum ExceptionMode {
|
||||
ABORT,
|
||||
NSRESULT,
|
||||
IGNORE;
|
||||
|
||||
public AnnotationInfo(String aWrapperName, boolean aIsMultithreaded,
|
||||
boolean aNoThrow, boolean aNarrowChars, boolean aCatchException) {
|
||||
wrapperName = aWrapperName;
|
||||
isMultithreaded = aIsMultithreaded;
|
||||
noThrow = aNoThrow;
|
||||
narrowChars = aNarrowChars;
|
||||
catchException = aCatchException;
|
||||
|
||||
if (noThrow && catchException) {
|
||||
// It doesn't make sense to have these together
|
||||
throw new IllegalArgumentException("noThrow and catchException are not allowed together");
|
||||
String nativeValue() {
|
||||
return "mozilla::jni::ExceptionMode::" + name();
|
||||
}
|
||||
}
|
||||
|
||||
public enum CallingThread {
|
||||
GECKO,
|
||||
UI,
|
||||
ANY;
|
||||
|
||||
String nativeValue() {
|
||||
return "mozilla::jni::CallingThread::" + name();
|
||||
}
|
||||
}
|
||||
|
||||
public enum DispatchTarget {
|
||||
GECKO,
|
||||
PROXY,
|
||||
CURRENT;
|
||||
|
||||
String nativeValue() {
|
||||
return "mozilla::jni::DispatchTarget::" + name();
|
||||
}
|
||||
}
|
||||
|
||||
public final String wrapperName;
|
||||
public final ExceptionMode exceptionMode;
|
||||
public final CallingThread callingThread;
|
||||
public final DispatchTarget dispatchTarget;
|
||||
|
||||
public AnnotationInfo(String wrapperName, ExceptionMode exceptionMode,
|
||||
CallingThread callingThread, DispatchTarget dispatchTarget) {
|
||||
|
||||
this.wrapperName = wrapperName;
|
||||
this.exceptionMode = exceptionMode;
|
||||
this.callingThread = callingThread;
|
||||
this.dispatchTarget = dispatchTarget;
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public class CodeGenerator {
|
||||
|
||||
private final Class<?> cls;
|
||||
private final String clsName;
|
||||
private boolean isMultithreaded;
|
||||
private AnnotationInfo.CallingThread callingThread = null;
|
||||
private int numNativesInits;
|
||||
|
||||
private final HashSet<String> takenMethodNames = new HashSet<String>();
|
||||
@ -39,13 +39,13 @@ public class CodeGenerator {
|
||||
final String unqualifiedName = Utils.getUnqualifiedName(clsName);
|
||||
header.append(
|
||||
"class " + clsName + " : public mozilla::jni::ObjectBase<" +
|
||||
unqualifiedName + ", jobject>\n" +
|
||||
unqualifiedName + ">\n" +
|
||||
"{\n" +
|
||||
"public:\n" +
|
||||
" static const char name[];\n" +
|
||||
"\n" +
|
||||
" explicit " + unqualifiedName + "(const Context& ctx) : ObjectBase<" +
|
||||
unqualifiedName + ", jobject>(ctx) {}\n" +
|
||||
unqualifiedName + ">(ctx) {}\n" +
|
||||
"\n");
|
||||
|
||||
cpp.append(
|
||||
@ -123,10 +123,11 @@ public class CodeGenerator {
|
||||
" \"" + Utils.getSignature(member) + "\";\n" +
|
||||
" static const bool isStatic = " + Utils.isStatic(member) + ";\n" +
|
||||
" static const mozilla::jni::ExceptionMode exceptionMode =\n" +
|
||||
" " + (
|
||||
info.catchException ? "mozilla::jni::ExceptionMode::NSRESULT" :
|
||||
info.noThrow ? "mozilla::jni::ExceptionMode::IGNORE" :
|
||||
"mozilla::jni::ExceptionMode::ABORT") + ";\n" +
|
||||
" " + info.exceptionMode.nativeValue() + ";\n" +
|
||||
" static const mozilla::jni::CallingThread callingThread =\n" +
|
||||
" " + info.callingThread.nativeValue() + ";\n" +
|
||||
" static const mozilla::jni::DispatchTarget dispatchTarget =\n" +
|
||||
" " + info.dispatchTarget.nativeValue() + ";\n" +
|
||||
" };\n" +
|
||||
"\n");
|
||||
|
||||
@ -137,7 +138,12 @@ public class CodeGenerator {
|
||||
"::signature[];\n" +
|
||||
"\n");
|
||||
|
||||
this.isMultithreaded |= info.isMultithreaded;
|
||||
if (this.callingThread == null) {
|
||||
this.callingThread = info.callingThread;
|
||||
} else if (this.callingThread != info.callingThread) {
|
||||
// We have a mix of calling threads, so specify "any" for the whole class.
|
||||
this.callingThread = AnnotationInfo.CallingThread.ANY;
|
||||
}
|
||||
}
|
||||
|
||||
private String getUniqueMethodName(String basename) {
|
||||
@ -180,7 +186,8 @@ public class CodeGenerator {
|
||||
proto.append(", ");
|
||||
}
|
||||
|
||||
if (info.catchException && !returnType.equals(void.class)) {
|
||||
if (info.exceptionMode == AnnotationInfo.ExceptionMode.NSRESULT &&
|
||||
!returnType.equals(void.class)) {
|
||||
proto.append(getNativeReturnType(returnType, info)).append('*');
|
||||
if (includeArgName) {
|
||||
proto.append(" a").append(argIndex++);
|
||||
@ -198,7 +205,7 @@ public class CodeGenerator {
|
||||
proto.append(" const");
|
||||
}
|
||||
|
||||
if (info.catchException) {
|
||||
if (info.exceptionMode == AnnotationInfo.ExceptionMode.NSRESULT) {
|
||||
proto.append(" -> nsresult");
|
||||
} else {
|
||||
proto.append(" -> ").append(getNativeReturnType(returnType, info));
|
||||
@ -238,12 +245,13 @@ public class CodeGenerator {
|
||||
// We initialize rv to NS_OK instead of NS_ERROR_* because loading NS_OK (0) uses
|
||||
// fewer instructions. We are guaranteed to set rv to the correct value later.
|
||||
|
||||
if (info.catchException && returnType.equals(void.class)) {
|
||||
if (info.exceptionMode == AnnotationInfo.ExceptionMode.NSRESULT &&
|
||||
returnType.equals(void.class)) {
|
||||
def.append(
|
||||
" nsresult rv = NS_OK;\n" +
|
||||
" ");
|
||||
|
||||
} else if (info.catchException) {
|
||||
} else if (info.exceptionMode == AnnotationInfo.ExceptionMode.NSRESULT) {
|
||||
// Non-void return type
|
||||
final String resultArg = "a" + argTypes.length;
|
||||
def.append(
|
||||
@ -263,7 +271,7 @@ public class CodeGenerator {
|
||||
.append(Utils.getUnqualifiedName(clsName) +
|
||||
(isStatic ? "::Context()" : "::mCtx"));
|
||||
|
||||
if (info.catchException) {
|
||||
if (info.exceptionMode == AnnotationInfo.ExceptionMode.NSRESULT) {
|
||||
def.append(", &rv");
|
||||
} else {
|
||||
def.append(", nullptr");
|
||||
@ -277,7 +285,7 @@ public class CodeGenerator {
|
||||
def.append(");\n");
|
||||
|
||||
|
||||
if (info.catchException) {
|
||||
if (info.exceptionMode == AnnotationInfo.ExceptionMode.NSRESULT) {
|
||||
def.append(" return rv;\n");
|
||||
}
|
||||
|
||||
@ -301,6 +309,13 @@ public class CodeGenerator {
|
||||
return;
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
if (info.dispatchTarget != AnnotationInfo.DispatchTarget.CURRENT) {
|
||||
throw new IllegalStateException("Invalid dispatch target \"" +
|
||||
info.dispatchTarget.name().toLowerCase() +
|
||||
"\" for non-native method " + clsName + "::" + uniqueName);
|
||||
}
|
||||
|
||||
generateMember(info, method, uniqueName, returnType, argTypes);
|
||||
|
||||
final boolean isStatic = Utils.isStatic(method);
|
||||
@ -331,6 +346,20 @@ public class CodeGenerator {
|
||||
final Class<?>[] argTypes = method.getParameterTypes();
|
||||
final Class<?> returnType = method.getReturnType();
|
||||
|
||||
// Sanity check
|
||||
if (info.exceptionMode != AnnotationInfo.ExceptionMode.ABORT &&
|
||||
info.exceptionMode != AnnotationInfo.ExceptionMode.IGNORE) {
|
||||
throw new IllegalStateException("Invalid exception mode \"" +
|
||||
info.exceptionMode.name().toLowerCase() +
|
||||
"\" for native method " + clsName + "::" + uniqueName);
|
||||
}
|
||||
if (info.dispatchTarget != AnnotationInfo.DispatchTarget.CURRENT &&
|
||||
returnType != void.class) {
|
||||
throw new IllegalStateException(
|
||||
"Must return void when not dispatching to current thread for native method " +
|
||||
clsName + "::" + uniqueName);
|
||||
}
|
||||
|
||||
generateMember(info, method, uniqueName, returnType, argTypes);
|
||||
|
||||
final String traits = getTraitsName(uniqueName, /* includeScope */ true);
|
||||
@ -360,7 +389,7 @@ public class CodeGenerator {
|
||||
|
||||
} else if (type.equals(CharSequence.class) || type.equals(String.class)) {
|
||||
final CharSequence str = (CharSequence) val;
|
||||
final StringBuilder out = new StringBuilder(info.narrowChars ? "u8\"" : "u\"");
|
||||
final StringBuilder out = new StringBuilder("u\"");
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
final char c = str.charAt(i);
|
||||
if (c >= 0x20 && c < 0x7F) {
|
||||
@ -387,6 +416,13 @@ public class CodeGenerator {
|
||||
return;
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
if (info.dispatchTarget != AnnotationInfo.DispatchTarget.CURRENT) {
|
||||
throw new IllegalStateException("Invalid dispatch target \"" +
|
||||
info.dispatchTarget.name().toLowerCase() +
|
||||
"\" for field " + clsName + "::" + uniqueName);
|
||||
}
|
||||
|
||||
final boolean isStatic = Utils.isStatic(field);
|
||||
final boolean isFinal = Utils.isFinal(field);
|
||||
|
||||
@ -407,7 +443,7 @@ public class CodeGenerator {
|
||||
return;
|
||||
|
||||
} else if (val != null && type.equals(String.class)) {
|
||||
final String nativeType = info.narrowChars ? "char" : "char16_t";
|
||||
final String nativeType = "char16_t";
|
||||
|
||||
header.append(
|
||||
" static const " + nativeType + ' ' + info.wrapperName + "[];\n" +
|
||||
@ -471,6 +507,13 @@ public class CodeGenerator {
|
||||
return;
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
if (info.dispatchTarget != AnnotationInfo.DispatchTarget.CURRENT) {
|
||||
throw new IllegalStateException("Invalid dispatch target \"" +
|
||||
info.dispatchTarget.name().toLowerCase() +
|
||||
"\" for constructor " + clsName + "::" + uniqueName);
|
||||
}
|
||||
|
||||
generateMember(info, method, uniqueName, returnType, argTypes);
|
||||
|
||||
header.append(
|
||||
@ -495,9 +538,11 @@ public class CodeGenerator {
|
||||
String name = Utils.getMemberName(m);
|
||||
name = name.substring(0, 1).toUpperCase() + name.substring(1);
|
||||
|
||||
// Default for SDK bindings.
|
||||
final AnnotationInfo info = new AnnotationInfo(name,
|
||||
/* multithread */ true, /* nothrow */ false,
|
||||
/* narrow */ false, /* catchException */ true);
|
||||
AnnotationInfo.ExceptionMode.NSRESULT,
|
||||
AnnotationInfo.CallingThread.ANY,
|
||||
AnnotationInfo.DispatchTarget.CURRENT);
|
||||
final AnnotatableEntity entity = new AnnotatableEntity(m, info);
|
||||
|
||||
if (m instanceof Constructor) {
|
||||
@ -541,8 +586,13 @@ public class CodeGenerator {
|
||||
* @return The bytes to be written to the header file.
|
||||
*/
|
||||
public String getHeaderFileContents() {
|
||||
if (this.callingThread == null) {
|
||||
this.callingThread = AnnotationInfo.CallingThread.ANY;
|
||||
}
|
||||
|
||||
header.append(
|
||||
" static const bool isMultithreaded = " + this.isMultithreaded + ";\n" +
|
||||
" static const mozilla::jni::CallingThread callingThread =\n" +
|
||||
" " + this.callingThread.nativeValue() + ";\n" +
|
||||
"\n");
|
||||
|
||||
if (nativesInits.length() > 0) {
|
||||
|
@ -30,6 +30,7 @@ public class GeneratableElementIterator implements Iterator<AnnotatableEntity> {
|
||||
private AnnotationInfo mClassInfo;
|
||||
|
||||
private boolean mIterateEveryEntry;
|
||||
private boolean mSkipCurrentEntry;
|
||||
|
||||
public GeneratableElementIterator(ClassWithOptions annotatedClass) {
|
||||
mClass = annotatedClass;
|
||||
@ -63,6 +64,10 @@ public class GeneratableElementIterator implements Iterator<AnnotatableEntity> {
|
||||
}
|
||||
}
|
||||
|
||||
if (mSkipCurrentEntry) {
|
||||
throw new IllegalArgumentException("Cannot skip entire class");
|
||||
}
|
||||
|
||||
findNextValue();
|
||||
}
|
||||
|
||||
@ -116,6 +121,32 @@ public class GeneratableElementIterator implements Iterator<AnnotatableEntity> {
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static <T extends Enum<T>> T getEnumValue(Class<T> type, String name)
|
||||
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
|
||||
try {
|
||||
return Enum.valueOf(type, name.toUpperCase());
|
||||
|
||||
} catch (IllegalArgumentException e) {
|
||||
Object[] values = (Object[]) type.getDeclaredMethod("values").invoke(null);
|
||||
StringBuilder names = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
if (i != 0) {
|
||||
names.append(", ");
|
||||
}
|
||||
names.append(values[i].toString().toLowerCase());
|
||||
}
|
||||
|
||||
System.err.println("***");
|
||||
System.err.println("*** Invalid value \"" + name + "\" for " + type.getSimpleName());
|
||||
System.err.println("*** Specify one of " + names.toString());
|
||||
System.err.println("***");
|
||||
e.printStackTrace(System.err);
|
||||
System.exit(6);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private AnnotationInfo buildAnnotationInfo(AnnotatedElement element, Annotation annotation) {
|
||||
Class<? extends Annotation> annotationType = annotation.annotationType();
|
||||
final String annotationTypeName = annotationType.getName();
|
||||
@ -124,41 +155,40 @@ public class GeneratableElementIterator implements Iterator<AnnotatableEntity> {
|
||||
}
|
||||
|
||||
String stubName = null;
|
||||
boolean isMultithreadedStub = false;
|
||||
boolean noThrow = false;
|
||||
boolean narrowChars = false;
|
||||
boolean catchException = false;
|
||||
AnnotationInfo.ExceptionMode exceptionMode = null;
|
||||
AnnotationInfo.CallingThread callingThread = null;
|
||||
AnnotationInfo.DispatchTarget dispatchTarget = null;
|
||||
|
||||
try {
|
||||
final Method skipMethod = annotationType.getDeclaredMethod("skip");
|
||||
skipMethod.setAccessible(true);
|
||||
if ((Boolean) skipMethod.invoke(annotation)) {
|
||||
mSkipCurrentEntry = true;
|
||||
return null;
|
||||
}
|
||||
|
||||
// Determine the explicitly-given name of the stub to generate, if any.
|
||||
final Method stubNameMethod = annotationType.getDeclaredMethod("stubName");
|
||||
stubNameMethod.setAccessible(true);
|
||||
stubName = (String) stubNameMethod.invoke(annotation);
|
||||
|
||||
if (element instanceof Class<?>) {
|
||||
// Make @WrapForJNI always allow multithread by default, individual methods can then
|
||||
// override with their own annotation
|
||||
isMultithreadedStub = true;
|
||||
} else {
|
||||
// Determine if the generated stub is to allow calls from multiple threads.
|
||||
final Method multithreadedStubMethod = annotationType.getDeclaredMethod("allowMultithread");
|
||||
multithreadedStubMethod.setAccessible(true);
|
||||
isMultithreadedStub = (Boolean) multithreadedStubMethod.invoke(annotation);
|
||||
}
|
||||
final Method exceptionModeMethod = annotationType.getDeclaredMethod("exceptionMode");
|
||||
exceptionModeMethod.setAccessible(true);
|
||||
exceptionMode = getEnumValue(
|
||||
AnnotationInfo.ExceptionMode.class,
|
||||
(String) exceptionModeMethod.invoke(annotation));
|
||||
|
||||
// Determine if ignoring exceptions
|
||||
final Method noThrowMethod = annotationType.getDeclaredMethod("noThrow");
|
||||
noThrowMethod.setAccessible(true);
|
||||
noThrow = (Boolean) noThrowMethod.invoke(annotation);
|
||||
final Method calledFromMethod = annotationType.getDeclaredMethod("calledFrom");
|
||||
calledFromMethod.setAccessible(true);
|
||||
callingThread = getEnumValue(
|
||||
AnnotationInfo.CallingThread.class,
|
||||
(String) calledFromMethod.invoke(annotation));
|
||||
|
||||
// Determine if strings should be wide or narrow
|
||||
final Method narrowCharsMethod = annotationType.getDeclaredMethod("narrowChars");
|
||||
narrowCharsMethod.setAccessible(true);
|
||||
narrowChars = (Boolean) narrowCharsMethod.invoke(annotation);
|
||||
|
||||
// Determine if we should catch exceptions
|
||||
final Method catchExceptionMethod = annotationType.getDeclaredMethod("catchException");
|
||||
catchExceptionMethod.setAccessible(true);
|
||||
catchException = (Boolean) catchExceptionMethod.invoke(annotation);
|
||||
final Method dispatchToMethod = annotationType.getDeclaredMethod("dispatchTo");
|
||||
dispatchToMethod.setAccessible(true);
|
||||
dispatchTarget = getEnumValue(
|
||||
AnnotationInfo.DispatchTarget.class,
|
||||
(String) dispatchToMethod.invoke(annotation));
|
||||
|
||||
} catch (NoSuchMethodException e) {
|
||||
System.err.println("Unable to find expected field on WrapForJNI annotation. Did the signature change?");
|
||||
@ -179,8 +209,7 @@ public class GeneratableElementIterator implements Iterator<AnnotatableEntity> {
|
||||
stubName = Utils.getNativeName(element);
|
||||
}
|
||||
|
||||
return new AnnotationInfo(
|
||||
stubName, isMultithreadedStub, noThrow, narrowChars, catchException);
|
||||
return new AnnotationInfo(stubName, exceptionMode, callingThread, dispatchTarget);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -199,15 +228,19 @@ public class GeneratableElementIterator implements Iterator<AnnotatableEntity> {
|
||||
}
|
||||
}
|
||||
|
||||
if (mSkipCurrentEntry) {
|
||||
mSkipCurrentEntry = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If no annotation found, we might be expected to generate anyway
|
||||
// using default arguments, thanks to the "Generate everything" annotation.
|
||||
if (mIterateEveryEntry) {
|
||||
AnnotationInfo annotationInfo = new AnnotationInfo(
|
||||
Utils.getNativeName(candidateElement),
|
||||
mClassInfo.isMultithreaded,
|
||||
mClassInfo.noThrow,
|
||||
mClassInfo.narrowChars,
|
||||
mClassInfo.catchException);
|
||||
mClassInfo.exceptionMode,
|
||||
mClassInfo.callingThread,
|
||||
mClassInfo.dispatchTarget);
|
||||
mNextReturnValue = new AnnotatableEntity(candidateElement, annotationInfo);
|
||||
return;
|
||||
}
|
||||
|
@ -45,7 +45,6 @@ LoadContext::LoadContext(nsIPrincipal* aPrincipal,
|
||||
: mTopFrameElement(nullptr)
|
||||
, mNestedFrameId(0)
|
||||
, mIsContent(true)
|
||||
, mUsePrivateBrowsing(false)
|
||||
, mUseRemoteTabs(false)
|
||||
#ifdef DEBUG
|
||||
, mIsNotNull(true)
|
||||
@ -53,7 +52,7 @@ LoadContext::LoadContext(nsIPrincipal* aPrincipal,
|
||||
{
|
||||
PrincipalOriginAttributes poa = BasePrincipal::Cast(aPrincipal)->OriginAttributesRef();
|
||||
mOriginAttributes.InheritFromDocToChildDocShell(poa);
|
||||
mOriginAttributes.SyncAttributesWithPrivateBrowsing(mUsePrivateBrowsing);
|
||||
mUsePrivateBrowsing = (poa.mPrivateBrowsingId != 0);
|
||||
if (!aOptionalBase) {
|
||||
return;
|
||||
}
|
||||
|
@ -11111,7 +11111,7 @@ nsDocShell::DoURILoad(nsIURI* aURI,
|
||||
return rv;
|
||||
}
|
||||
|
||||
static NS_METHOD
|
||||
static nsresult
|
||||
AppendSegmentToString(nsIInputStream* aIn,
|
||||
void* aClosure,
|
||||
const char* aFromRawSegment,
|
||||
|
@ -143,7 +143,7 @@
|
||||
#include "mozilla/dom/KeyframeEffectBinding.h"
|
||||
#include "mozilla/dom/WindowBinding.h"
|
||||
#include "mozilla/dom/ElementBinding.h"
|
||||
#include "mozilla/dom/VRDevice.h"
|
||||
#include "mozilla/dom/VRDisplay.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsComputedDOMStyle.h"
|
||||
@ -3305,10 +3305,8 @@ GetFullScreenError(nsIDocument* aDoc)
|
||||
}
|
||||
|
||||
void
|
||||
Element::RequestFullscreen(JSContext* aCx, JS::Handle<JS::Value> aOptions,
|
||||
ErrorResult& aError)
|
||||
Element::RequestFullscreen(ErrorResult& aError)
|
||||
{
|
||||
MOZ_ASSERT_IF(!aCx, aOptions.isNullOrUndefined());
|
||||
// Only grant full-screen requests if this is called from inside a trusted
|
||||
// event handler (i.e. inside an event handler for a user initiated event).
|
||||
// This stops the full-screen from being abused similar to the popups of old,
|
||||
@ -3324,29 +3322,6 @@ Element::RequestFullscreen(JSContext* aCx, JS::Handle<JS::Value> aOptions,
|
||||
auto request = MakeUnique<FullscreenRequest>(this);
|
||||
request->mIsCallerChrome = nsContentUtils::IsCallerChrome();
|
||||
|
||||
RequestFullscreenOptions fsOptions;
|
||||
// We need to check if options is convertible to a dict first before
|
||||
// trying to init fsOptions; otherwise Init() would throw, and we want to
|
||||
// silently ignore non-dictionary values
|
||||
if (aCx) {
|
||||
bool convertible;
|
||||
if (!IsConvertibleToDictionary(aCx, aOptions, &convertible)) {
|
||||
aError.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (convertible) {
|
||||
if (!fsOptions.Init(aCx, aOptions)) {
|
||||
aError.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fsOptions.mVrDisplay) {
|
||||
request->mVRHMDDevice = fsOptions.mVrDisplay->GetHMD();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OwnerDoc()->AsyncRequestFullScreen(Move(request));
|
||||
}
|
||||
|
||||
|
@ -774,9 +774,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// aCx == nullptr is allowed only if aOptions.isNullOrUndefined()
|
||||
void RequestFullscreen(JSContext* aCx, JS::Handle<JS::Value> aOptions,
|
||||
ErrorResult& aError);
|
||||
void RequestFullscreen(ErrorResult& aError);
|
||||
void RequestPointerLock();
|
||||
Attr* GetAttributeNode(const nsAString& aName);
|
||||
already_AddRefed<Attr> SetAttributeNode(Attr& aNewAttr,
|
||||
@ -1879,7 +1877,7 @@ NS_IMETHOD ReleaseCapture(void) final override \
|
||||
NS_IMETHOD MozRequestFullScreen(void) final override \
|
||||
{ \
|
||||
mozilla::ErrorResult rv; \
|
||||
Element::RequestFullscreen(nullptr, JS::UndefinedHandleValue, rv); \
|
||||
Element::RequestFullscreen(rv); \
|
||||
return rv.StealNSResult(); \
|
||||
} \
|
||||
NS_IMETHOD MozRequestPointerLock(void) final override \
|
||||
|
@ -375,7 +375,7 @@ EventSource::OnStartRequest(nsIRequest *aRequest,
|
||||
|
||||
// this method parses the characters as they become available instead of
|
||||
// buffering them.
|
||||
NS_METHOD
|
||||
nsresult
|
||||
EventSource::StreamReaderFunc(nsIInputStream *aInputStream,
|
||||
void *aClosure,
|
||||
const char *aFromRawSegment,
|
||||
|
@ -127,12 +127,12 @@ protected:
|
||||
uint32_t aFormatStringsLen);
|
||||
nsresult ConsoleError();
|
||||
|
||||
static NS_METHOD StreamReaderFunc(nsIInputStream *aInputStream,
|
||||
void *aClosure,
|
||||
const char *aFromRawSegment,
|
||||
uint32_t aToOffset,
|
||||
uint32_t aCount,
|
||||
uint32_t *aWriteCount);
|
||||
static nsresult StreamReaderFunc(nsIInputStream *aInputStream,
|
||||
void *aClosure,
|
||||
const char *aFromRawSegment,
|
||||
uint32_t aToOffset,
|
||||
uint32_t aCount,
|
||||
uint32_t *aWriteCount);
|
||||
nsresult SetFieldAndClear();
|
||||
nsresult ClearFields();
|
||||
nsresult ResetEvent();
|
||||
|
@ -181,7 +181,7 @@ FileReader::GetResult(JSContext* aCx,
|
||||
}
|
||||
}
|
||||
|
||||
static NS_METHOD
|
||||
static nsresult
|
||||
ReadFuncBinaryString(nsIInputStream* in,
|
||||
void* closure,
|
||||
const char* fromRawSegment,
|
||||
|
@ -112,7 +112,7 @@
|
||||
|
||||
#include "mozAutoDocUpdate.h"
|
||||
|
||||
#include "mozilla/Snprintf.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
#include "nsDOMMutationObserver.h"
|
||||
#include "nsWrapperCacheInlines.h"
|
||||
#include "nsCycleCollector.h"
|
||||
@ -1894,13 +1894,13 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(FragmentOrElement)
|
||||
}
|
||||
|
||||
const char* nsuri = nsid < ArrayLength(kNSURIs) ? kNSURIs[nsid] : "";
|
||||
snprintf_literal(name, "FragmentOrElement%s %s%s%s%s %s",
|
||||
nsuri,
|
||||
localName.get(),
|
||||
NS_ConvertUTF16toUTF8(id).get(),
|
||||
NS_ConvertUTF16toUTF8(classes).get(),
|
||||
orphan.get(),
|
||||
uri.get());
|
||||
SprintfLiteral(name, "FragmentOrElement%s %s%s%s%s %s",
|
||||
nsuri,
|
||||
localName.get(),
|
||||
NS_ConvertUTF16toUTF8(id).get(),
|
||||
NS_ConvertUTF16toUTF8(classes).get(),
|
||||
orphan.get(),
|
||||
uri.get());
|
||||
cb.DescribeRefCountedNode(tmp->mRefCnt.get(), name);
|
||||
}
|
||||
else {
|
||||
|
@ -51,7 +51,7 @@
|
||||
#include "mozilla/dom/Telephony.h"
|
||||
#include "mozilla/dom/Voicemail.h"
|
||||
#include "mozilla/dom/TVManager.h"
|
||||
#include "mozilla/dom/VRDevice.h"
|
||||
#include "mozilla/dom/VRDisplay.h"
|
||||
#include "mozilla/dom/workers/RuntimeService.h"
|
||||
#include "mozilla/Hal.h"
|
||||
#include "nsISiteSpecificUserAgent.h"
|
||||
@ -267,7 +267,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Navigator)
|
||||
#ifdef MOZ_GAMEPAD
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGamepadServiceTest)
|
||||
#endif
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVRGetDevicesPromises)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVRGetDisplaysPromises)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
@ -412,7 +412,7 @@ Navigator::Invalidate()
|
||||
}
|
||||
#endif
|
||||
|
||||
mVRGetDevicesPromises.Clear();
|
||||
mVRGetDisplaysPromises.Clear();
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
@ -2037,48 +2037,51 @@ Navigator::RequestGamepadServiceTest()
|
||||
#endif
|
||||
|
||||
already_AddRefed<Promise>
|
||||
Navigator::GetVRDevices(ErrorResult& aRv)
|
||||
Navigator::GetVRDisplays(ErrorResult& aRv)
|
||||
{
|
||||
if (!mWindow || !mWindow->GetDocShell()) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsGlobalWindow* win = nsGlobalWindow::Cast(mWindow);
|
||||
win->NotifyVREventListenerAdded();
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
|
||||
RefPtr<Promise> p = Promise::Create(go, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// We pass ourself to RefreshVRDevices, so NotifyVRDevicesUpdated will
|
||||
// be called asynchronously, resolving the promises in mVRGetDevicesPromises.
|
||||
if (!VRDevice::RefreshVRDevices(this)) {
|
||||
// We pass ourself to RefreshVRDisplays, so NotifyVRDisplaysUpdated will
|
||||
// be called asynchronously, resolving the promises in mVRGetDisplaysPromises.
|
||||
if (!VRDisplay::RefreshVRDisplays(this)) {
|
||||
p->MaybeReject(NS_ERROR_FAILURE);
|
||||
return p.forget();
|
||||
}
|
||||
|
||||
mVRGetDevicesPromises.AppendElement(p);
|
||||
mVRGetDisplaysPromises.AppendElement(p);
|
||||
return p.forget();
|
||||
}
|
||||
|
||||
void
|
||||
Navigator::NotifyVRDevicesUpdated()
|
||||
Navigator::NotifyVRDisplaysUpdated()
|
||||
{
|
||||
// Synchronize the VR devices and resolve the promises in
|
||||
// mVRGetDevicesPromises
|
||||
// mVRGetDisplaysPromises
|
||||
nsGlobalWindow* win = nsGlobalWindow::Cast(mWindow);
|
||||
|
||||
nsTArray<RefPtr<VRDevice>> vrDevs;
|
||||
if (win->UpdateVRDevices(vrDevs)) {
|
||||
for (auto p: mVRGetDevicesPromises) {
|
||||
p->MaybeResolve(vrDevs);
|
||||
nsTArray<RefPtr<VRDisplay>> vrDisplays;
|
||||
if (win->UpdateVRDisplays(vrDisplays)) {
|
||||
for (auto p : mVRGetDisplaysPromises) {
|
||||
p->MaybeResolve(vrDisplays);
|
||||
}
|
||||
} else {
|
||||
for (auto p: mVRGetDevicesPromises) {
|
||||
for (auto p : mVRGetDisplaysPromises) {
|
||||
p->MaybeReject(NS_ERROR_FAILURE);
|
||||
}
|
||||
}
|
||||
mVRGetDevicesPromises.Clear();
|
||||
mVRGetDisplaysPromises.Clear();
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
|
@ -101,6 +101,7 @@ class InputPortManager;
|
||||
class DeviceStorageAreaListener;
|
||||
class Presentation;
|
||||
class LegacyMozTCPSocket;
|
||||
class VRDisplay;
|
||||
|
||||
namespace time {
|
||||
class TimeManager;
|
||||
@ -260,8 +261,8 @@ public:
|
||||
void GetGamepads(nsTArray<RefPtr<Gamepad> >& aGamepads, ErrorResult& aRv);
|
||||
GamepadServiceTest* RequestGamepadServiceTest();
|
||||
#endif // MOZ_GAMEPAD
|
||||
already_AddRefed<Promise> GetVRDevices(ErrorResult& aRv);
|
||||
void NotifyVRDevicesUpdated();
|
||||
already_AddRefed<Promise> GetVRDisplays(ErrorResult& aRv);
|
||||
void NotifyVRDisplaysUpdated();
|
||||
#ifdef MOZ_B2G_FM
|
||||
FMRadio* GetMozFMRadio(ErrorResult& aRv);
|
||||
#endif
|
||||
@ -394,7 +395,7 @@ private:
|
||||
#ifdef MOZ_GAMEPAD
|
||||
RefPtr<GamepadServiceTest> mGamepadServiceTest;
|
||||
#endif
|
||||
nsTArray<RefPtr<Promise> > mVRGetDevicesPromises;
|
||||
nsTArray<RefPtr<Promise> > mVRGetDisplaysPromises;
|
||||
nsTArray<uint32_t> mRequestedVibrationPattern;
|
||||
};
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include "nsCRT.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "mozilla/Snprintf.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsCCUncollectableMarker.h"
|
||||
@ -129,11 +129,11 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(NodeInfo)
|
||||
uint32_t nsid = tmp->NamespaceID();
|
||||
nsAtomCString localName(tmp->NameAtom());
|
||||
if (nsid < ArrayLength(kNodeInfoNSURIs)) {
|
||||
snprintf_literal(name, "NodeInfo%s %s", kNodeInfoNSURIs[nsid],
|
||||
localName.get());
|
||||
SprintfLiteral(name, "NodeInfo%s %s", kNodeInfoNSURIs[nsid],
|
||||
localName.get());
|
||||
}
|
||||
else {
|
||||
snprintf_literal(name, "NodeInfo %s", localName.get());
|
||||
SprintfLiteral(name, "NodeInfo %s", localName.get());
|
||||
}
|
||||
|
||||
cb.DescribeRefCountedNode(tmp->mRefCnt.get(), name);
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
#include "mozilla/Logging.h"
|
||||
#include "plstr.h"
|
||||
#include "mozilla/Snprintf.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
@ -243,7 +243,6 @@
|
||||
#include "nsLocation.h"
|
||||
#include "mozilla/dom/FontFaceSet.h"
|
||||
#include "mozilla/dom/BoxObject.h"
|
||||
#include "gfxVR.h"
|
||||
#include "gfxPrefs.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "mozilla/StyleSetHandle.h"
|
||||
@ -1764,12 +1763,12 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument)
|
||||
if (tmp->mDocumentURI)
|
||||
tmp->mDocumentURI->GetSpec(uri);
|
||||
if (nsid < ArrayLength(kNSURIs)) {
|
||||
snprintf_literal(name, "nsDocument %s %s %s",
|
||||
loadedAsData.get(), kNSURIs[nsid], uri.get());
|
||||
SprintfLiteral(name, "nsDocument %s %s %s",
|
||||
loadedAsData.get(), kNSURIs[nsid], uri.get());
|
||||
}
|
||||
else {
|
||||
snprintf_literal(name, "nsDocument %s %s",
|
||||
loadedAsData.get(), uri.get());
|
||||
SprintfLiteral(name, "nsDocument %s %s",
|
||||
loadedAsData.get(), uri.get());
|
||||
}
|
||||
cb.DescribeRefCountedNode(tmp->mRefCnt.get(), name);
|
||||
}
|
||||
@ -2951,9 +2950,9 @@ GetFormattedTimeString(PRTime aTime, nsAString& aFormattedTimeString)
|
||||
PR_ExplodeTime(aTime, PR_LocalTimeParameters, &prtime);
|
||||
// "MM/DD/YYYY hh:mm:ss"
|
||||
char formatedTime[24];
|
||||
if (snprintf_literal(formatedTime, "%02d/%02d/%04d %02d:%02d:%02d",
|
||||
prtime.tm_month + 1, prtime.tm_mday, int(prtime.tm_year),
|
||||
prtime.tm_hour , prtime.tm_min, prtime.tm_sec)) {
|
||||
if (SprintfLiteral(formatedTime, "%02d/%02d/%04d %02d:%02d:%02d",
|
||||
prtime.tm_month + 1, prtime.tm_mday, int(prtime.tm_year),
|
||||
prtime.tm_hour , prtime.tm_min, prtime.tm_sec)) {
|
||||
CopyASCIItoUTF16(nsDependentCString(formatedTime), aFormattedTimeString);
|
||||
} else {
|
||||
// If we for whatever reason failed to find the last modified time
|
||||
@ -11496,8 +11495,6 @@ UpdateViewportScrollbarOverrideForFullscreen(nsIDocument* aDoc)
|
||||
static void
|
||||
ClearFullscreenStateOnElement(Element* aElement)
|
||||
{
|
||||
// Remove any VR state properties
|
||||
aElement->DeleteProperty(nsGkAtoms::vr_state);
|
||||
// Remove styles from existing top element.
|
||||
EventStateManager::SetFullScreenState(aElement, false);
|
||||
// Reset iframe fullscreen flag.
|
||||
@ -11669,14 +11666,6 @@ nsDocument::IsUnprefixedFullscreenEnabled(JSContext* aCx, JSObject* aObject)
|
||||
nsContentUtils::IsUnprefixedFullscreenApiEnabled();
|
||||
}
|
||||
|
||||
static void
|
||||
ReleaseVRDeviceProxyRef(void *, nsIAtom*, void *aPropertyValue, void *)
|
||||
{
|
||||
if (aPropertyValue) {
|
||||
static_cast<gfx::VRDeviceProxy*>(aPropertyValue)->Release();
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
HasFullScreenSubDocument(nsIDocument* aDoc)
|
||||
{
|
||||
@ -11957,10 +11946,7 @@ nsDocument::RequestFullScreen(UniquePtr<FullscreenRequest>&& aRequest)
|
||||
/* Bubbles */ true, /* Cancelable */ false, /* DefaultAction */ nullptr);
|
||||
} else {
|
||||
// Make the window fullscreen.
|
||||
const FullscreenRequest*
|
||||
lastRequest = PendingFullscreenRequestList::GetLast();
|
||||
rootWin->SetFullscreenInternal(FullscreenReason::ForFullscreenAPI, true,
|
||||
lastRequest->mVRHMDDevice);
|
||||
rootWin->SetFullscreenInternal(FullscreenReason::ForFullscreenAPI, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -12017,13 +12003,6 @@ nsDocument::ApplyFullscreen(const FullscreenRequest& aRequest)
|
||||
// before setting a new document to fullscreen
|
||||
UnlockPointer();
|
||||
|
||||
// Process options -- in this case, just HMD
|
||||
if (aRequest.mVRHMDDevice) {
|
||||
RefPtr<gfx::VRDeviceProxy> hmdRef = aRequest.mVRHMDDevice;
|
||||
elem->SetProperty(nsGkAtoms::vr_state, hmdRef.forget().take(),
|
||||
ReleaseVRDeviceProxyRef, true);
|
||||
}
|
||||
|
||||
// Set the full-screen element. This sets the full-screen style on the
|
||||
// element, and the full-screen-ancestor styles on ancestors of the element
|
||||
// in this document.
|
||||
|
@ -112,7 +112,6 @@ private:
|
||||
RefPtr<nsDocument> mDocument;
|
||||
|
||||
public:
|
||||
RefPtr<gfx::VRDeviceProxy> mVRHMDDevice;
|
||||
// This value should be true if the fullscreen request is
|
||||
// originated from chrome code.
|
||||
bool mIsCallerChrome = false;
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include "nsTextNode.h"
|
||||
|
||||
#include "PLDHashTable.h"
|
||||
#include "mozilla/Snprintf.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
#include "nsWrapperCacheInlines.h"
|
||||
|
||||
using namespace mozilla;
|
||||
@ -91,8 +91,8 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGenericDOMDataNode)
|
||||
if (MOZ_UNLIKELY(cb.WantDebugInfo())) {
|
||||
char name[40];
|
||||
snprintf_literal(name, "nsGenericDOMDataNode (len=%d)",
|
||||
tmp->mText.GetLength());
|
||||
SprintfLiteral(name, "nsGenericDOMDataNode (len=%d)",
|
||||
tmp->mText.GetLength());
|
||||
cb.DescribeRefCountedNode(tmp->mRefCnt.get(), name);
|
||||
} else {
|
||||
NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsGenericDOMDataNode, tmp->mRefCnt.get())
|
||||
@ -430,7 +430,7 @@ nsGenericDOMDataNode::ToCString(nsAString& aBuf, int32_t aOffset,
|
||||
aBuf.AppendLiteral(">");
|
||||
} else if ((ch < ' ') || (ch >= 127)) {
|
||||
char buf[10];
|
||||
snprintf_literal(buf, "\\u%04x", ch);
|
||||
SprintfLiteral(buf, "\\u%04x", ch);
|
||||
AppendASCIItoUTF16(buf, aBuf);
|
||||
} else {
|
||||
aBuf.Append(ch);
|
||||
@ -450,7 +450,7 @@ nsGenericDOMDataNode::ToCString(nsAString& aBuf, int32_t aOffset,
|
||||
aBuf.AppendLiteral(">");
|
||||
} else if ((ch < ' ') || (ch >= 127)) {
|
||||
char buf[10];
|
||||
snprintf_literal(buf, "\\u%04x", ch);
|
||||
SprintfLiteral(buf, "\\u%04x", ch);
|
||||
AppendASCIItoUTF16(buf, aBuf);
|
||||
} else {
|
||||
aBuf.Append(ch);
|
||||
|
@ -948,6 +948,9 @@ GK_ATOM(onussdreceived, "onussdreceived")
|
||||
GK_ATOM(onversionchange, "onversionchange")
|
||||
GK_ATOM(onvoicechange, "onvoicechange")
|
||||
GK_ATOM(onvoiceschanged, "onvoiceschanged")
|
||||
GK_ATOM(onvrdisplayconnect, "onvrdisplayconnect")
|
||||
GK_ATOM(onvrdisplaydisconnect, "onvrdisplaydisconnect")
|
||||
GK_ATOM(onvrdisplaypresentchange, "onvrdisplaypresentchange")
|
||||
GK_ATOM(onwebkitAnimationEnd, "onwebkitAnimationEnd")
|
||||
GK_ATOM(onwebkitAnimationIteration, "onwebkitAnimationIteration")
|
||||
GK_ATOM(onwebkitAnimationStart, "onwebkitAnimationStart")
|
||||
@ -2450,8 +2453,6 @@ GK_ATOM(onmark, "onmark")
|
||||
GK_ATOM(onboundary, "onboundary")
|
||||
#endif
|
||||
|
||||
GK_ATOM(vr_state, "vr-state")
|
||||
|
||||
// Contextual Identity / Containers
|
||||
GK_ATOM(usercontextid, "usercontextid")
|
||||
|
||||
|
@ -59,7 +59,7 @@
|
||||
#include "ScriptSettings.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Likely.h"
|
||||
#include "mozilla/Snprintf.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
#include "mozilla/unused.h"
|
||||
|
||||
// Other Classes
|
||||
@ -192,7 +192,8 @@
|
||||
#include "mozilla/dom/GamepadManager.h"
|
||||
#endif
|
||||
|
||||
#include "mozilla/dom/VRDevice.h"
|
||||
#include "mozilla/dom/VRDisplay.h"
|
||||
#include "mozilla/dom/VREventObserver.h"
|
||||
|
||||
#include "nsRefreshDriver.h"
|
||||
#include "Layers.h"
|
||||
@ -1200,6 +1201,7 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
|
||||
mShowFocusRingForContent(false),
|
||||
mFocusByKeyOccurred(false),
|
||||
mHasGamepad(false),
|
||||
mHasVREvents(false),
|
||||
#ifdef MOZ_GAMEPAD
|
||||
mHasSeenGamepadInput(false),
|
||||
#endif
|
||||
@ -1599,11 +1601,14 @@ nsGlobalWindow::CleanUp()
|
||||
if (IsInnerWindow()) {
|
||||
DisableGamepadUpdates();
|
||||
mHasGamepad = false;
|
||||
DisableVRUpdates();
|
||||
mHasVREvents = false;
|
||||
#ifdef MOZ_B2G
|
||||
DisableTimeChangeNotifications();
|
||||
#endif
|
||||
} else {
|
||||
MOZ_ASSERT(!mHasGamepad);
|
||||
MOZ_ASSERT(!mHasVREvents);
|
||||
}
|
||||
|
||||
if (mCleanMessageManager) {
|
||||
@ -1743,6 +1748,9 @@ nsGlobalWindow::FreeInnerObjects()
|
||||
mHasGamepad = false;
|
||||
mGamepads.Clear();
|
||||
#endif
|
||||
DisableVRUpdates();
|
||||
mHasVREvents = false;
|
||||
mVRDisplays.Clear();
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
@ -1837,8 +1845,8 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindow)
|
||||
if (tmp->mDoc && tmp->mDoc->GetDocumentURI()) {
|
||||
tmp->mDoc->GetDocumentURI()->GetSpec(uri);
|
||||
}
|
||||
snprintf_literal(name, "nsGlobalWindow # %" PRIu64 " %s %s", tmp->mWindowID,
|
||||
tmp->IsInnerWindow() ? "inner" : "outer", uri.get());
|
||||
SprintfLiteral(name, "nsGlobalWindow # %" PRIu64 " %s %s", tmp->mWindowID,
|
||||
tmp->IsInnerWindow() ? "inner" : "outer", uri.get());
|
||||
cb.DescribeRefCountedNode(tmp->mRefCnt.get(), name);
|
||||
} else {
|
||||
NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsGlobalWindow, tmp->mRefCnt.get())
|
||||
@ -1891,7 +1899,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindow)
|
||||
#endif
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCacheStorage)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVRDevices)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVRDisplays)
|
||||
|
||||
// Traverse stuff from nsPIDOMWindow
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChromeEventHandler)
|
||||
@ -1967,7 +1975,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindow)
|
||||
#endif
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCacheStorage)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mVRDevices)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mVRDisplays)
|
||||
|
||||
// Unlink stuff from nsPIDOMWindow
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mChromeEventHandler)
|
||||
@ -6308,8 +6316,8 @@ FullscreenTransitionTask::Observer::Observe(nsISupports* aSubject,
|
||||
}
|
||||
|
||||
static bool
|
||||
MakeWidgetFullscreen(nsGlobalWindow* aWindow, gfx::VRDeviceProxy* aHMD,
|
||||
FullscreenReason aReason, bool aFullscreen)
|
||||
MakeWidgetFullscreen(nsGlobalWindow* aWindow, FullscreenReason aReason,
|
||||
bool aFullscreen)
|
||||
{
|
||||
nsCOMPtr<nsIWidget> widget = aWindow->GetMainWidget();
|
||||
if (!widget) {
|
||||
@ -6326,13 +6334,16 @@ MakeWidgetFullscreen(nsGlobalWindow* aWindow, gfx::VRDeviceProxy* aHMD,
|
||||
PrepareForFullscreenTransition(getter_AddRefs(transitionData));
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsIScreen> screen = aHMD ? aHMD->GetScreen() : nullptr;
|
||||
// We pass nullptr as the screen to SetWidgetFullscreen
|
||||
// and FullscreenTransitionTask, as we do not wish to override
|
||||
// the default screen selection behavior. The screen containing
|
||||
// most of the widget will be selected.
|
||||
if (!performTransition) {
|
||||
return aWindow->SetWidgetFullscreen(aReason, aFullscreen, widget, screen);
|
||||
return aWindow->SetWidgetFullscreen(aReason, aFullscreen, widget, nullptr);
|
||||
} else {
|
||||
nsCOMPtr<nsIRunnable> task =
|
||||
new FullscreenTransitionTask(duration, aWindow, aFullscreen,
|
||||
widget, screen, transitionData);
|
||||
widget, nullptr, transitionData);
|
||||
task->Run();
|
||||
return true;
|
||||
}
|
||||
@ -6340,8 +6351,7 @@ MakeWidgetFullscreen(nsGlobalWindow* aWindow, gfx::VRDeviceProxy* aHMD,
|
||||
|
||||
nsresult
|
||||
nsGlobalWindow::SetFullscreenInternal(FullscreenReason aReason,
|
||||
bool aFullScreen,
|
||||
gfx::VRDeviceProxy* aHMD)
|
||||
bool aFullScreen)
|
||||
{
|
||||
MOZ_ASSERT(IsOuterWindow());
|
||||
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript(),
|
||||
@ -6370,7 +6380,7 @@ nsGlobalWindow::SetFullscreenInternal(FullscreenReason aReason,
|
||||
if (!window)
|
||||
return NS_ERROR_FAILURE;
|
||||
if (rootItem != mDocShell)
|
||||
return window->SetFullscreenInternal(aReason, aFullScreen, aHMD);
|
||||
return window->SetFullscreenInternal(aReason, aFullScreen);
|
||||
|
||||
// make sure we don't try to set full screen on a non-chrome window,
|
||||
// which might happen in embedding world
|
||||
@ -6421,7 +6431,7 @@ nsGlobalWindow::SetFullscreenInternal(FullscreenReason aReason,
|
||||
// dimensions to appear to increase when entering fullscreen mode; we just
|
||||
// want the content to fill the entire client area of the emulator window.
|
||||
if (!Preferences::GetBool("full-screen-api.ignore-widgets", false)) {
|
||||
if (MakeWidgetFullscreen(this, aHMD, aReason, aFullScreen)) {
|
||||
if (MakeWidgetFullscreen(this, aReason, aFullScreen)) {
|
||||
// The rest of code for switching fullscreen is in nsGlobalWindow::
|
||||
// FinishFullscreenChange() which will be called after sizemodechange
|
||||
// event is dispatched.
|
||||
@ -9880,6 +9890,24 @@ nsGlobalWindow::DisableGamepadUpdates()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsGlobalWindow::EnableVRUpdates()
|
||||
{
|
||||
MOZ_ASSERT(IsInnerWindow());
|
||||
|
||||
if (mHasVREvents && !mVREventObserver) {
|
||||
mVREventObserver = new VREventObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsGlobalWindow::DisableVRUpdates()
|
||||
{
|
||||
MOZ_ASSERT(IsInnerWindow());
|
||||
|
||||
mVREventObserver = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
nsGlobalWindow::SetChromeEventHandler(EventTarget* aChromeEventHandler)
|
||||
{
|
||||
@ -12930,6 +12958,7 @@ nsGlobalWindow::SuspendTimeouts(uint32_t aIncrease,
|
||||
ac->RemoveWindowListener(mEnabledSensors[i], this);
|
||||
}
|
||||
DisableGamepadUpdates();
|
||||
DisableVRUpdates();
|
||||
|
||||
// Freeze or suspend all of the workers for this window.
|
||||
if (aFreezeWorkers) {
|
||||
@ -13016,6 +13045,7 @@ nsGlobalWindow::ResumeTimeouts(bool aThawChildren, bool aThawWorkers)
|
||||
ac->AddWindowListener(mEnabledSensors[i], this);
|
||||
}
|
||||
EnableGamepadUpdates();
|
||||
EnableVRUpdates();
|
||||
|
||||
// Resume all of the AudioContexts for this window
|
||||
for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
|
||||
@ -13206,6 +13236,25 @@ nsGlobalWindow::SetHasGamepadEventListener(bool aHasGamepad/* = true*/)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsGlobalWindow::EventListenerAdded(nsIAtom* aType)
|
||||
{
|
||||
if (aType == nsGkAtoms::onvrdisplayconnect ||
|
||||
aType == nsGkAtoms::onvrdisplaydisconnect ||
|
||||
aType == nsGkAtoms::onvrdisplaypresentchange) {
|
||||
NotifyVREventListenerAdded();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsGlobalWindow::NotifyVREventListenerAdded()
|
||||
{
|
||||
MOZ_ASSERT(IsInnerWindow());
|
||||
mHasVREvents = true;
|
||||
EnableVRUpdates();
|
||||
}
|
||||
|
||||
void
|
||||
nsGlobalWindow::EnableTimeChangeNotifications()
|
||||
{
|
||||
@ -13349,12 +13398,12 @@ nsGlobalWindow::SyncGamepadState()
|
||||
#endif // MOZ_GAMEPAD
|
||||
|
||||
bool
|
||||
nsGlobalWindow::UpdateVRDevices(nsTArray<RefPtr<mozilla::dom::VRDevice>>& aDevices)
|
||||
nsGlobalWindow::UpdateVRDisplays(nsTArray<RefPtr<mozilla::dom::VRDisplay>>& aDevices)
|
||||
{
|
||||
FORWARD_TO_INNER(UpdateVRDevices, (aDevices), false);
|
||||
FORWARD_TO_INNER(UpdateVRDisplays, (aDevices), false);
|
||||
|
||||
VRDevice::UpdateVRDevices(mVRDevices, ToSupports(this));
|
||||
aDevices = mVRDevices;
|
||||
VRDisplay::UpdateVRDisplays(mVRDisplays, AsInner());
|
||||
aDevices = mVRDisplays;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -122,7 +122,8 @@ class RequestOrUSVString;
|
||||
class Selection;
|
||||
class SpeechSynthesis;
|
||||
class U2F;
|
||||
class VRDevice;
|
||||
class VRDisplay;
|
||||
class VREventObserver;
|
||||
class WakeLock;
|
||||
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
|
||||
class WindowOrientationObserver;
|
||||
@ -132,9 +133,6 @@ class CacheStorage;
|
||||
} // namespace cache
|
||||
class IDBFactory;
|
||||
} // namespace dom
|
||||
namespace gfx {
|
||||
class VRDeviceProxy;
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
extern already_AddRefed<nsIScriptTimeoutHandler>
|
||||
@ -491,8 +489,7 @@ public:
|
||||
|
||||
// Outer windows only.
|
||||
virtual nsresult SetFullscreenInternal(
|
||||
FullscreenReason aReason, bool aIsFullscreen,
|
||||
mozilla::gfx::VRDeviceProxy *aHMD = nullptr) override final;
|
||||
FullscreenReason aReason, bool aIsFullscreen) override final;
|
||||
virtual void FinishFullscreenChange(bool aIsFullscreen) override final;
|
||||
bool SetWidgetFullscreen(FullscreenReason aReason, bool aIsFullscreen,
|
||||
nsIWidget* aWidget, nsIScreen* aScreen);
|
||||
@ -500,6 +497,8 @@ public:
|
||||
|
||||
// Inner windows only.
|
||||
virtual void SetHasGamepadEventListener(bool aHasGamepad = true) override;
|
||||
void NotifyVREventListenerAdded();
|
||||
virtual void EventListenerAdded(nsIAtom* aType) override;
|
||||
|
||||
// nsIInterfaceRequestor
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
@ -805,8 +804,13 @@ public:
|
||||
void EnableGamepadUpdates();
|
||||
void DisableGamepadUpdates();
|
||||
|
||||
// Update the VR devices for this window
|
||||
bool UpdateVRDevices(nsTArray<RefPtr<mozilla::dom::VRDevice>>& aDevices);
|
||||
// Inner windows only.
|
||||
// Enable/disable updates for VR
|
||||
void EnableVRUpdates();
|
||||
void DisableVRUpdates();
|
||||
|
||||
// Update the VR displays for this window
|
||||
bool UpdateVRDisplays(nsTArray<RefPtr<mozilla::dom::VRDisplay>>& aDisplays);
|
||||
|
||||
#define EVENT(name_, id_, type_, struct_) \
|
||||
mozilla::dom::EventHandlerNonNull* GetOn##name_() \
|
||||
@ -1770,6 +1774,10 @@ protected:
|
||||
// Inner windows only.
|
||||
// Indicates whether this window wants gamepad input events
|
||||
bool mHasGamepad : 1;
|
||||
|
||||
// Inner windows only.
|
||||
// Indicates whether this window wants VR events
|
||||
bool mHasVREvents : 1;
|
||||
#ifdef MOZ_GAMEPAD
|
||||
nsCheapSet<nsUint32HashKey> mGamepadIndexSet;
|
||||
nsRefPtrHashtable<nsUint32HashKey, mozilla::dom::Gamepad> mGamepads;
|
||||
@ -1912,8 +1920,10 @@ protected:
|
||||
// This is the CC generation the last time we called CanSkip.
|
||||
uint32_t mCanSkipCCGeneration;
|
||||
|
||||
// The VRDevies for this window
|
||||
nsTArray<RefPtr<mozilla::dom::VRDevice>> mVRDevices;
|
||||
// The VR Displays for this window
|
||||
nsTArray<RefPtr<mozilla::dom::VRDisplay>> mVRDisplays;
|
||||
|
||||
nsAutoPtr<mozilla::dom::VREventObserver> mVREventObserver;
|
||||
|
||||
friend class nsDOMScriptableHelper;
|
||||
friend class nsDOMWindowUtils;
|
||||
|
@ -46,9 +46,6 @@ class Performance;
|
||||
class ServiceWorkerRegistration;
|
||||
class CustomElementsRegistry;
|
||||
} // namespace dom
|
||||
namespace gfx {
|
||||
class VRDeviceProxy;
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
// Popup control state enum. The values in this enum must go from most
|
||||
@ -339,14 +336,10 @@ public:
|
||||
* Moves the top-level window into fullscreen mode if aIsFullScreen is true,
|
||||
* otherwise exits fullscreen.
|
||||
*
|
||||
* If aHMD is not null, the window is made full screen on the given VR HMD
|
||||
* device instead of its currrent display.
|
||||
*
|
||||
* Outer windows only.
|
||||
*/
|
||||
virtual nsresult SetFullscreenInternal(
|
||||
FullscreenReason aReason, bool aIsFullscreen,
|
||||
mozilla::gfx::VRDeviceProxy *aHMD = nullptr) = 0;
|
||||
FullscreenReason aReason, bool aIsFullscreen) = 0;
|
||||
|
||||
/**
|
||||
* This function should be called when the fullscreen state is flipped.
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include "nsNameSpaceManager.h"
|
||||
#include "nsTextFragment.h"
|
||||
#include "nsString.h"
|
||||
#include "mozilla/Snprintf.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsContentUtils.h"
|
||||
@ -608,7 +608,7 @@ nsXMLContentSerializer::GenerateNewPrefix(nsAString& aPrefix)
|
||||
{
|
||||
aPrefix.Assign('a');
|
||||
char buf[128];
|
||||
snprintf_literal(buf, "%d", mPrefixIndex++);
|
||||
SprintfLiteral(buf, "%d", mPrefixIndex++);
|
||||
AppendASCIItoUTF16(buf, aPrefix);
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include "xpcprivate.h"
|
||||
#include "XrayWrapper.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "mozilla/Snprintf.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
@ -2574,13 +2574,13 @@ ConvertJSValueToByteString(JSContext* cx, JS::Handle<JS::Value> v,
|
||||
// 20 digits, plus one more for the null terminator.
|
||||
char index[21];
|
||||
static_assert(sizeof(size_t) <= 8, "index array too small");
|
||||
snprintf_literal(index, "%" PRIuSIZE, badCharIndex);
|
||||
SprintfLiteral(index, "%" PRIuSIZE, badCharIndex);
|
||||
// A char16_t is 16 bits long. The biggest unsigned 16 bit
|
||||
// number (65,535) has 5 digits, plus one more for the null
|
||||
// terminator.
|
||||
char badCharArray[6];
|
||||
static_assert(sizeof(char16_t) <= 2, "badCharArray too small");
|
||||
snprintf_literal(badCharArray, "%d", badChar);
|
||||
SprintfLiteral(badCharArray, "%d", badChar);
|
||||
ThrowErrorMessage(cx, MSG_INVALID_BYTESTRING, index, badCharArray);
|
||||
return false;
|
||||
}
|
||||
|
@ -1233,10 +1233,6 @@ DOMInterfaces = {
|
||||
'implicitJSContext' : [ 'undo', 'redo', 'transact' ],
|
||||
},
|
||||
|
||||
'VRDevice': {
|
||||
'concrete': False
|
||||
},
|
||||
|
||||
'VTTCue': {
|
||||
'nativeType': 'mozilla::dom::TextTrackCue'
|
||||
},
|
||||
|
@ -48,6 +48,8 @@
|
||||
#include "nsSVGEffects.h"
|
||||
#include "prenv.h"
|
||||
#include "ScopedGLHelpers.h"
|
||||
#include "VRManagerChild.h"
|
||||
#include "mozilla/layers/TextureClientSharedSurface.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include "mozilla/layers/ShadowLayers.h"
|
||||
@ -123,6 +125,7 @@ WebGLContext::WebGLContext()
|
||||
, mNeedsFakeNoDepth(false)
|
||||
, mNeedsFakeNoStencil(false)
|
||||
, mNeedsEmulatedLoneDepthStencil(false)
|
||||
, mVRPresentationActive(false)
|
||||
{
|
||||
mGeneration = 0;
|
||||
mInvalidated = false;
|
||||
@ -2179,8 +2182,8 @@ ZeroTexImageWithClear(WebGLContext* webgl, GLContext* gl, TexImageTarget target,
|
||||
}
|
||||
|
||||
bool
|
||||
ZeroTextureData(WebGLContext* webgl, const char* funcName, bool respecifyTexture,
|
||||
GLuint tex, TexImageTarget target, uint32_t level,
|
||||
ZeroTextureData(WebGLContext* webgl, const char* funcName, GLuint tex,
|
||||
TexImageTarget target, uint32_t level,
|
||||
const webgl::FormatUsageInfo* usage, uint32_t xOffset, uint32_t yOffset,
|
||||
uint32_t zOffset, uint32_t width, uint32_t height, uint32_t depth)
|
||||
{
|
||||
@ -2203,7 +2206,6 @@ ZeroTextureData(WebGLContext* webgl, const char* funcName, bool respecifyTexture
|
||||
auto compression = usage->format->compression;
|
||||
if (compression) {
|
||||
MOZ_RELEASE_ASSERT(!xOffset && !yOffset && !zOffset, "GFX: Can't zero compressed texture with offsets.");
|
||||
MOZ_RELEASE_ASSERT(!respecifyTexture, "GFX: respecifyTexture is set to true.");
|
||||
|
||||
auto sizedFormat = usage->format->sizedFormat;
|
||||
MOZ_RELEASE_ASSERT(sizedFormat, "GFX: texture sized format not set");
|
||||
@ -2251,13 +2253,6 @@ ZeroTextureData(WebGLContext* webgl, const char* funcName, bool respecifyTexture
|
||||
// While we would like to skip the extra complexity of trying to zero with an FB
|
||||
// clear, ANGLE_depth_texture requires this.
|
||||
do {
|
||||
if (respecifyTexture) {
|
||||
const auto error = DoTexImage(gl, target, level, driverUnpackInfo, width,
|
||||
height, depth, nullptr);
|
||||
if (error)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ZeroTexImageWithClear(webgl, gl, target, tex, level, usage, width,
|
||||
height))
|
||||
{
|
||||
@ -2287,15 +2282,8 @@ ZeroTextureData(WebGLContext* webgl, const char* funcName, bool respecifyTexture
|
||||
ScopedUnpackReset scopedReset(webgl);
|
||||
gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 1); // Don't bother with striding it well.
|
||||
|
||||
GLenum error;
|
||||
if (respecifyTexture) {
|
||||
MOZ_RELEASE_ASSERT(!xOffset && !yOffset && !zOffset, "GFX: texture data, offsets, not zeroed.");
|
||||
error = DoTexImage(gl, target, level, driverUnpackInfo, width, height, depth,
|
||||
zeros.get());
|
||||
} else {
|
||||
error = DoTexSubImage(gl, target, level, xOffset, yOffset, zOffset, width, height,
|
||||
depth, packing, zeros.get());
|
||||
}
|
||||
const auto error = DoTexSubImage(gl, target, level, xOffset, yOffset, zOffset, width,
|
||||
height, depth, packing, zeros.get());
|
||||
if (error)
|
||||
return false;
|
||||
|
||||
@ -2349,6 +2337,72 @@ WebGLContext::GetUnpackSize(bool isFunc3D, uint32_t width, uint32_t height,
|
||||
return totalBytes;
|
||||
}
|
||||
|
||||
already_AddRefed<layers::SharedSurfaceTextureClient>
|
||||
WebGLContext::GetVRFrame()
|
||||
{
|
||||
VRManagerChild *vrmc = VRManagerChild::Get();
|
||||
if (!vrmc) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PresentScreenBuffer();
|
||||
mDrawCallsSinceLastFlush = 0;
|
||||
|
||||
MarkContextClean();
|
||||
UpdateLastUseIndex();
|
||||
|
||||
gl::GLScreenBuffer* screen = gl->Screen();
|
||||
if (!screen) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<SharedSurfaceTextureClient> sharedSurface = screen->Front();
|
||||
if (!sharedSurface) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (sharedSurface && sharedSurface->GetAllocator() != vrmc) {
|
||||
RefPtr<SharedSurfaceTextureClient> dest =
|
||||
screen->Factory()->NewTexClient(sharedSurface->GetSize());
|
||||
if (!dest) {
|
||||
return nullptr;
|
||||
}
|
||||
gl::SharedSurface* destSurf = dest->Surf();
|
||||
destSurf->ProducerAcquire();
|
||||
SharedSurface::ProdCopy(sharedSurface->Surf(), dest->Surf(), screen->Factory());
|
||||
destSurf->ProducerRelease();
|
||||
|
||||
return dest.forget();
|
||||
}
|
||||
|
||||
return sharedSurface.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLContext::StartVRPresentation()
|
||||
{
|
||||
VRManagerChild *vrmc = VRManagerChild::Get();
|
||||
if (!vrmc) {
|
||||
return false;
|
||||
}
|
||||
gl::GLScreenBuffer* screen = gl->Screen();
|
||||
if (!screen) {
|
||||
return false;
|
||||
}
|
||||
gl::SurfaceCaps caps = screen->mCaps;
|
||||
|
||||
UniquePtr<gl::SurfaceFactory> factory =
|
||||
gl::GLScreenBuffer::CreateFactory(gl,
|
||||
caps,
|
||||
vrmc,
|
||||
vrmc->GetBackendType(),
|
||||
TextureFlags::ORIGIN_BOTTOM_LEFT);
|
||||
|
||||
screen->Morph(Move(factory));
|
||||
mVRPresentationActive = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// XPCOM goop
|
||||
|
||||
|
@ -116,6 +116,7 @@ template<typename> struct Nullable;
|
||||
|
||||
namespace gfx {
|
||||
class SourceSurface;
|
||||
class VRLayerChild;
|
||||
} // namespace gfx
|
||||
|
||||
namespace webgl {
|
||||
@ -539,6 +540,9 @@ public:
|
||||
void LinkProgram(WebGLProgram* prog);
|
||||
void PixelStorei(GLenum pname, GLint param);
|
||||
void PolygonOffset(GLfloat factor, GLfloat units);
|
||||
|
||||
already_AddRefed<layers::SharedSurfaceTextureClient> GetVRFrame();
|
||||
bool StartVRPresentation();
|
||||
protected:
|
||||
bool ReadPixels_SharedPrecheck(ErrorResult* const out_error);
|
||||
void ReadPixelsImpl(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
|
||||
@ -1474,6 +1478,7 @@ protected:
|
||||
bool mNeedsFakeNoDepth;
|
||||
bool mNeedsFakeNoStencil;
|
||||
bool mNeedsEmulatedLoneDepthStencil;
|
||||
bool mVRPresentationActive;
|
||||
|
||||
bool HasTimestampBits() const;
|
||||
|
||||
@ -1756,8 +1761,8 @@ Intersect(uint32_t srcSize, int32_t dstStartInSrc, uint32_t dstSize,
|
||||
uint32_t* const out_intSize);
|
||||
|
||||
bool
|
||||
ZeroTextureData(WebGLContext* webgl, const char* funcName, bool respecifyTexture,
|
||||
GLuint tex, TexImageTarget target, uint32_t level,
|
||||
ZeroTextureData(WebGLContext* webgl, const char* funcName, GLuint tex,
|
||||
TexImageTarget target, uint32_t level,
|
||||
const webgl::FormatUsageInfo* usage, uint32_t xOffset, uint32_t yOffset,
|
||||
uint32_t zOffset, uint32_t width, uint32_t height, uint32_t depth);
|
||||
|
||||
|
@ -591,14 +591,13 @@ WebGLTexture::InitializeImageData(const char* funcName, TexImageTarget target,
|
||||
MOZ_ASSERT(imageInfo.IsDefined());
|
||||
MOZ_ASSERT(!imageInfo.IsDataInitialized());
|
||||
|
||||
const bool respecifyTexture = false;
|
||||
const auto& usage = imageInfo.mFormat;
|
||||
const auto& width = imageInfo.mWidth;
|
||||
const auto& height = imageInfo.mHeight;
|
||||
const auto& depth = imageInfo.mDepth;
|
||||
|
||||
if (!ZeroTextureData(mContext, funcName, respecifyTexture, mGLName, target, level,
|
||||
usage, 0, 0, 0, width, height, depth))
|
||||
if (!ZeroTextureData(mContext, funcName, mGLName, target, level, usage, 0, 0, 0,
|
||||
width, height, depth))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -2072,17 +2072,24 @@ WebGLTexture::CopyTexImage2D(TexImageTarget target, GLint level, GLenum internal
|
||||
Intersect(srcWidth, x, width, &readX, &writeX, &rwWidth);
|
||||
Intersect(srcHeight, y, height, &readY, &writeY, &rwHeight);
|
||||
|
||||
GLenum error;
|
||||
if (rwWidth == uint32_t(width) && rwHeight == uint32_t(height)) {
|
||||
error = DoCopyTexImage2D(gl, target, level, internalFormat, x, y, width, height);
|
||||
} else {
|
||||
const auto& idealUnpack = dstUsage->idealUnpack;
|
||||
const auto& driverInternalFormat = idealUnpack->internalFormat;
|
||||
|
||||
GLenum error = DoCopyTexImage2D(gl, target, level, driverInternalFormat, x, y, width,
|
||||
height);
|
||||
do {
|
||||
if (rwWidth == uint32_t(width) && rwHeight == uint32_t(height))
|
||||
break;
|
||||
|
||||
if (error)
|
||||
break;
|
||||
|
||||
// 1. Zero the texture data.
|
||||
// 2. CopyTexSubImage the subrect.
|
||||
|
||||
const bool respecifyTexture = true;
|
||||
const uint8_t zOffset = 0;
|
||||
if (!ZeroTextureData(mContext, funcName, respecifyTexture, mGLName, target, level,
|
||||
dstUsage, 0, 0, zOffset, width, height, depth))
|
||||
if (!ZeroTextureData(mContext, funcName, mGLName, target, level, dstUsage, 0, 0,
|
||||
zOffset, width, height, depth))
|
||||
{
|
||||
mContext->ErrorOutOfMemory("%s: Failed to zero texture data.", funcName);
|
||||
MOZ_ASSERT(false, "Failed to zero texture data.");
|
||||
@ -2097,7 +2104,7 @@ WebGLTexture::CopyTexImage2D(TexImageTarget target, GLint level, GLenum internal
|
||||
|
||||
error = DoCopyTexSubImage(gl, target, level, writeX, writeY, zOffset, readX,
|
||||
readY, rwWidth, rwHeight);
|
||||
}
|
||||
} while (false);
|
||||
|
||||
if (error == LOCAL_GL_OUT_OF_MEMORY) {
|
||||
mContext->ErrorOutOfMemory("%s: Ran out of memory during texture copy.",
|
||||
|
25
dom/canvas/crashtests/1283113-1.html
Normal file
25
dom/canvas/crashtests/1283113-1.html
Normal file
@ -0,0 +1,25 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
|
||||
function boom()
|
||||
{
|
||||
var canvas = document.createElement('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
ctx.transform(1,1,0,0,0,0);
|
||||
ctx.scale(610.561277214,0.0);
|
||||
ctx.scale(442.538892637,64.9064087241);
|
||||
ctx.scale(851.176724189,322.349092655);
|
||||
ctx.scale(862.937434575,2.88757032711);
|
||||
ctx.scale(230.933492526,766.024348731);
|
||||
ctx.scale(968.538114712,4.580);
|
||||
ctx.transform(1,0,1,0,1,0);
|
||||
ctx.scale(341.640607159,753.362567174);
|
||||
ctx.measureText('');
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="boom();"></body>
|
||||
</html>
|
20
dom/canvas/crashtests/1286458-1.html
Normal file
20
dom/canvas/crashtests/1286458-1.html
Normal file
@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
|
||||
function boom()
|
||||
{
|
||||
var canvas = document.createElement('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
var path=new Path2D();
|
||||
path.bezierCurveTo(436,Number.MIN_VALUE,620,Number.MAX_SAFE_INTEGER,1,83);
|
||||
ctx.setTransform(1,Number.MAX_SAFE_INTEGER,1,0,1,146.0);
|
||||
ctx.scale(16777218,55);
|
||||
ctx.stroke(path);
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="boom();"></body>
|
||||
</html>
|
@ -34,4 +34,6 @@ skip-if(d2d) load 1287515-1.html
|
||||
load 1287652-1.html
|
||||
load 1288872-1.html
|
||||
load 1290628-1.html
|
||||
load 1283113-1.html
|
||||
load 1286458-1.html
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "mozilla/Snprintf.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "ScriptSettings.h"
|
||||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
@ -35,9 +35,9 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(DOMEventTargetHelper)
|
||||
nsXPCOMCycleCollectionParticipant* participant = nullptr;
|
||||
CallQueryInterface(tmp, &participant);
|
||||
|
||||
snprintf_literal(name, "%s %s",
|
||||
participant->ClassName(),
|
||||
NS_ConvertUTF16toUTF8(uri).get());
|
||||
SprintfLiteral(name, "%s %s",
|
||||
participant->ClassName(),
|
||||
NS_ConvertUTF16toUTF8(uri).get());
|
||||
cb.DescribeRefCountedNode(tmp->mRefCnt.get(), name);
|
||||
} else {
|
||||
NS_IMPL_CYCLE_COLLECTION_DESCRIBE(DOMEventTargetHelper, tmp->mRefCnt.get())
|
||||
|
@ -599,7 +599,18 @@ WINDOW_ONLY_EVENT(devicelight,
|
||||
eDeviceLight,
|
||||
EventNameType_None,
|
||||
eBasicEventClass)
|
||||
|
||||
WINDOW_ONLY_EVENT(vrdisplayconnect,
|
||||
eVRDisplayConnect,
|
||||
EventNameType_None,
|
||||
eBasicEventClass)
|
||||
WINDOW_ONLY_EVENT(vrdisplaydisconnect,
|
||||
eVRDisplayDisconnect,
|
||||
EventNameType_None,
|
||||
eBasicEventClass)
|
||||
WINDOW_ONLY_EVENT(vrdisplaypresentchange,
|
||||
eVRDisplayPresentChange,
|
||||
EventNameType_None,
|
||||
eBasicEventClass)
|
||||
// Install events as per W3C Manifest spec
|
||||
WINDOW_ONLY_EVENT(install,
|
||||
eInstall,
|
||||
|
@ -390,7 +390,7 @@ HttpServer::Connection::OnInputStreamReady(nsIAsyncInputStream* aStream)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsresult
|
||||
HttpServer::Connection::ReadSegmentsFunc(nsIInputStream* aIn,
|
||||
void* aClosure,
|
||||
const char* aBuffer,
|
||||
@ -982,12 +982,12 @@ private:
|
||||
}
|
||||
~StreamCopier() {}
|
||||
|
||||
static NS_METHOD FillOutputBufferHelper(nsIOutputStream* aOutStr,
|
||||
void* aClosure,
|
||||
char* aBuffer,
|
||||
uint32_t aOffset,
|
||||
uint32_t aCount,
|
||||
uint32_t* aCountRead);
|
||||
static nsresult FillOutputBufferHelper(nsIOutputStream* aOutStr,
|
||||
void* aClosure,
|
||||
char* aBuffer,
|
||||
uint32_t aOffset,
|
||||
uint32_t aCount,
|
||||
uint32_t* aCountRead);
|
||||
nsresult FillOutputBuffer(char* aBuffer,
|
||||
uint32_t aCount,
|
||||
uint32_t* aCountRead);
|
||||
@ -1017,7 +1017,7 @@ struct WriteState
|
||||
|
||||
// This function only exists to enable FillOutputBuffer to be a non-static
|
||||
// function where we can use member variables more easily.
|
||||
NS_METHOD
|
||||
nsresult
|
||||
StreamCopier::FillOutputBufferHelper(nsIOutputStream* aOutStr,
|
||||
void* aClosure,
|
||||
char* aBuffer,
|
||||
@ -1030,7 +1030,7 @@ StreamCopier::FillOutputBufferHelper(nsIOutputStream* aOutStr,
|
||||
return ws->sourceRv;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsresult
|
||||
CheckForEOF(nsIInputStream* aIn,
|
||||
void* aClosure,
|
||||
const char* aBuffer,
|
||||
|
@ -129,12 +129,12 @@ private:
|
||||
|
||||
void SetSecurityObserver(bool aListen);
|
||||
|
||||
static NS_METHOD ReadSegmentsFunc(nsIInputStream* aIn,
|
||||
void* aClosure,
|
||||
const char* aBuffer,
|
||||
uint32_t aToOffset,
|
||||
uint32_t aCount,
|
||||
uint32_t* aWriteCount);
|
||||
static nsresult ReadSegmentsFunc(nsIInputStream* aIn,
|
||||
void* aClosure,
|
||||
const char* aBuffer,
|
||||
uint32_t aToOffset,
|
||||
uint32_t aCount,
|
||||
uint32_t* aWriteCount);
|
||||
nsresult ConsumeInput(const char*& aBuffer,
|
||||
const char* aEnd);
|
||||
nsresult ConsumeLine(const char* aBuffer,
|
||||
|
@ -13,17 +13,10 @@ namespace dom {
|
||||
|
||||
class AndroidGamepadManager final
|
||||
: public java::AndroidGamepadManager::Natives<AndroidGamepadManager>
|
||||
, public jni::UsesNativeCallProxy
|
||||
{
|
||||
AndroidGamepadManager() = delete;
|
||||
|
||||
public:
|
||||
template<class Functor>
|
||||
static void OnNativeCall(Functor&& aCall)
|
||||
{
|
||||
NS_DispatchToMainThread(NS_NewRunnableFunction(Move(aCall)));
|
||||
}
|
||||
|
||||
static void
|
||||
OnGamepadChange(int32_t aID, bool aAdded)
|
||||
{
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "nsRefreshDriver.h"
|
||||
#include "nsStreamUtils.h"
|
||||
#include "ActiveLayerTracker.h"
|
||||
#include "VRManagerChild.h"
|
||||
#include "WebGL1Context.h"
|
||||
#include "WebGL2Context.h"
|
||||
|
||||
@ -352,6 +353,7 @@ NS_IMPL_ISUPPORTS(HTMLCanvasElementObserver, nsIObserver)
|
||||
HTMLCanvasElement::HTMLCanvasElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
|
||||
: nsGenericHTMLElement(aNodeInfo),
|
||||
mResetLayer(true) ,
|
||||
mVRPresentationActive(false),
|
||||
mWriteOnly(false)
|
||||
{}
|
||||
|
||||
@ -1065,7 +1067,7 @@ HTMLCanvasElement::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
||||
static uint8_t sOffscreenCanvasLayerUserDataDummy = 0;
|
||||
|
||||
if (mCurrentContext) {
|
||||
return mCurrentContext->GetCanvasLayer(aBuilder, aOldLayer, aManager);
|
||||
return mCurrentContext->GetCanvasLayer(aBuilder, aOldLayer, aManager, mVRPresentationActive);
|
||||
}
|
||||
|
||||
if (mOffscreenCanvas) {
|
||||
@ -1383,5 +1385,42 @@ HTMLCanvasElement::InvalidateFromAsyncCanvasRenderer(AsyncCanvasRenderer *aRende
|
||||
element->InvalidateCanvasContent(nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
HTMLCanvasElement::StartVRPresentation()
|
||||
{
|
||||
WebGLContext* webgl = static_cast<WebGLContext*>(GetContextAtIndex(0));
|
||||
if (!webgl) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!webgl->StartVRPresentation()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mVRPresentationActive = true;
|
||||
}
|
||||
|
||||
void
|
||||
HTMLCanvasElement::StopVRPresentation()
|
||||
{
|
||||
mVRPresentationActive = false;
|
||||
}
|
||||
|
||||
already_AddRefed<layers::SharedSurfaceTextureClient>
|
||||
HTMLCanvasElement::GetVRFrame()
|
||||
{
|
||||
if (GetCurrentContextType() != CanvasContextType::WebGL1 &&
|
||||
GetCurrentContextType() != CanvasContextType::WebGL2) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
WebGLContext* webgl = static_cast<WebGLContext*>(GetContextAtIndex(0));
|
||||
if (!webgl) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return webgl->GetVRFrame();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -33,9 +33,11 @@ class CanvasLayer;
|
||||
class Image;
|
||||
class Layer;
|
||||
class LayerManager;
|
||||
class SharedSurfaceTextureClient;
|
||||
} // namespace layers
|
||||
namespace gfx {
|
||||
class SourceSurface;
|
||||
class VRLayerChild;
|
||||
} // namespace gfx
|
||||
|
||||
namespace dom {
|
||||
@ -342,6 +344,10 @@ public:
|
||||
static void SetAttrFromAsyncCanvasRenderer(AsyncCanvasRenderer *aRenderer);
|
||||
static void InvalidateFromAsyncCanvasRenderer(AsyncCanvasRenderer *aRenderer);
|
||||
|
||||
void StartVRPresentation();
|
||||
void StopVRPresentation();
|
||||
already_AddRefed<layers::SharedSurfaceTextureClient> GetVRFrame();
|
||||
|
||||
protected:
|
||||
virtual ~HTMLCanvasElement();
|
||||
|
||||
@ -375,6 +381,7 @@ protected:
|
||||
RefPtr<AsyncCanvasRenderer> mAsyncCanvasRenderer;
|
||||
RefPtr<OffscreenCanvas> mOffscreenCanvas;
|
||||
RefPtr<HTMLCanvasElementObserver> mContextObserver;
|
||||
bool mVRPresentationActive;
|
||||
|
||||
public:
|
||||
// Record whether this canvas should be write-only or not.
|
||||
|
@ -4,7 +4,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/. */
|
||||
#include "CrashReporterParent.h"
|
||||
#include "mozilla/Snprintf.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
@ -137,7 +137,7 @@ CrashReporterParent::GenerateChildData(const AnnotationTable* processNotes)
|
||||
mNotes.Put(NS_LITERAL_CSTRING("ProcessType"), type);
|
||||
|
||||
char startTime[32];
|
||||
snprintf_literal(startTime, "%lld", static_cast<long long>(mStartTime));
|
||||
SprintfLiteral(startTime, "%lld", static_cast<long long>(mStartTime));
|
||||
mNotes.Put(NS_LITERAL_CSTRING("StartupTime"), nsDependentCString(startTime));
|
||||
|
||||
if (!mAppNotes.IsEmpty()) {
|
||||
|
@ -110,6 +110,7 @@
|
||||
#include "nsDeviceContext.h"
|
||||
#include "nsSandboxFlags.h"
|
||||
#include "FrameLayerBuilder.h"
|
||||
#include "VRManagerChild.h"
|
||||
|
||||
#ifdef NS_PRINTING
|
||||
#include "nsIPrintSession.h"
|
||||
@ -2741,6 +2742,7 @@ TabChild::InitRenderingState(const TextureFactoryIdentifier& aTextureFactoryIden
|
||||
"PuppetWidget should have shadow manager");
|
||||
lf->IdentifyTextureHost(mTextureFactoryIdentifier);
|
||||
ImageBridgeChild::IdentifyCompositorTextureHost(mTextureFactoryIdentifier);
|
||||
gfx::VRManagerChild::IdentifyTextureHost(mTextureFactoryIdentifier);
|
||||
|
||||
mRemoteFrame = remoteFrame;
|
||||
if (aLayersId != 0) {
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include "VideoUtils.h"
|
||||
#include "mozilla/Monitor.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/Snprintf.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
#include <algorithm>
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "CubebUtils.h"
|
||||
@ -243,7 +243,7 @@ OpenDumpFile(uint32_t aChannels, uint32_t aRate)
|
||||
if (!getenv("MOZ_DUMP_AUDIO"))
|
||||
return nullptr;
|
||||
char buf[100];
|
||||
snprintf_literal(buf, "dumped-audio-%d.wav", ++gDumpedAudioCount);
|
||||
SprintfLiteral(buf, "dumped-audio-%d.wav", ++gDumpedAudioCount);
|
||||
FILE* f = fopen(buf, "wb");
|
||||
if (!f)
|
||||
return nullptr;
|
||||
|
@ -56,7 +56,7 @@
|
||||
#include "nsVariant.h"
|
||||
|
||||
// For snprintf
|
||||
#include "mozilla/Snprintf.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
|
||||
#include "nsJSUtils.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
@ -2767,7 +2767,7 @@ MediaManager::RemoveWindowID(uint64_t aWindowId)
|
||||
|
||||
// Notify the UI that this window no longer has gUM active
|
||||
char windowBuffer[32];
|
||||
snprintf_literal(windowBuffer, "%" PRIu64, outerID);
|
||||
SprintfLiteral(windowBuffer, "%" PRIu64, outerID);
|
||||
nsString data = NS_ConvertUTF8toUTF16(windowBuffer);
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
|
@ -425,7 +425,7 @@ struct CopySegmentClosure {
|
||||
ChannelMediaResource* mResource;
|
||||
};
|
||||
|
||||
NS_METHOD
|
||||
nsresult
|
||||
ChannelMediaResource::CopySegmentToCache(nsIInputStream *aInStream,
|
||||
void *aClosure,
|
||||
const char *aFromSegment,
|
||||
|
@ -668,12 +668,12 @@ protected:
|
||||
|
||||
void DoNotifyDataReceived();
|
||||
|
||||
static NS_METHOD CopySegmentToCache(nsIInputStream *aInStream,
|
||||
void *aClosure,
|
||||
const char *aFromSegment,
|
||||
uint32_t aToOffset,
|
||||
uint32_t aCount,
|
||||
uint32_t *aWriteCount);
|
||||
static nsresult CopySegmentToCache(nsIInputStream *aInStream,
|
||||
void *aClosure,
|
||||
const char *aFromSegment,
|
||||
uint32_t aToOffset,
|
||||
uint32_t aCount,
|
||||
uint32_t *aWriteCount);
|
||||
|
||||
// Main thread access only
|
||||
int64_t mOffset;
|
||||
|
@ -113,7 +113,7 @@ WebVTTListener::OnStopRequest(nsIRequest* aRequest,
|
||||
return aStatus;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsresult
|
||||
WebVTTListener::ParseChunk(nsIInputStream* aInStream, void* aClosure,
|
||||
const char* aFromSegment, uint32_t aToOffset,
|
||||
uint32_t aCount, uint32_t* aWriteCount)
|
||||
|
@ -50,9 +50,9 @@ private:
|
||||
enum ErrorCodes {
|
||||
BadSignature = 0
|
||||
};
|
||||
static NS_METHOD ParseChunk(nsIInputStream* aInStream, void* aClosure,
|
||||
const char* aFromSegment, uint32_t aToOffset,
|
||||
uint32_t aCount, uint32_t* aWriteCount);
|
||||
static nsresult ParseChunk(nsIInputStream* aInStream, void* aClosure,
|
||||
const char* aFromSegment, uint32_t aToOffset,
|
||||
uint32_t aCount, uint32_t* aWriteCount);
|
||||
|
||||
RefPtr<HTMLTrackElement> mElement;
|
||||
nsCOMPtr<nsIWebVTTParserWrapper> mParserWrapper;
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include "mozilla/Logging.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "mozilla/Snprintf.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
|
||||
struct JSContext;
|
||||
class JSObject;
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include "MediaData.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/Snprintf.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
|
||||
extern mozilla::LogModule* GetSourceBufferResourceLog();
|
||||
|
||||
@ -165,7 +165,7 @@ ResourceQueue::Dump(const char* aPath)
|
||||
ResourceItem* item = ResourceAt(i);
|
||||
|
||||
char buf[255];
|
||||
snprintf_literal(buf, "%s/%08u.bin", aPath, i);
|
||||
SprintfLiteral(buf, "%s/%08u.bin", aPath, i);
|
||||
FILE* fp = fopen(buf, "wb");
|
||||
if (!fp) {
|
||||
return;
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include "NesteggPacketHolder.h"
|
||||
#include "XiphExtradata.h"
|
||||
#include "prprf.h" // leaving it for PR_vsnprintf()
|
||||
#include "mozilla/Snprintf.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdint.h>
|
||||
@ -123,7 +123,7 @@ static void webmdemux_log(nestegg* aContext,
|
||||
|
||||
va_start(args, aFormat);
|
||||
|
||||
snprintf_literal(msg, "%p [Nestegg-%s] ", aContext, sevStr);
|
||||
SprintfLiteral(msg, "%p [Nestegg-%s] ", aContext, sevStr);
|
||||
PR_vsnprintf(msg+strlen(msg), sizeof(msg)-strlen(msg), aFormat, args);
|
||||
MOZ_LOG(gNesteggLog, LogLevel::Debug, (msg));
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "mozilla/dom/RTCCertificateBinding.h"
|
||||
#include "mozilla/dom/WebCryptoCommon.h"
|
||||
#include "mozilla/dom/WebCryptoTask.h"
|
||||
#include "mozilla/Snprintf.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsIMobileMessageDatabaseService.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::dom::mobilemessage;
|
||||
@ -47,16 +46,13 @@ SmsManager::NotifySmsReceived(int32_t aId,
|
||||
message.deliveryTimestamp() = aTimestamp;
|
||||
message.read() = false;
|
||||
|
||||
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=] () {
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
if (!obs) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
if (!obs) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISmsMessage> domMessage = new SmsMessageInternal(message);
|
||||
obs->NotifyObservers(domMessage, kSmsReceivedObserverTopic, nullptr);
|
||||
});
|
||||
NS_DispatchToMainThread(runnable);
|
||||
nsCOMPtr<nsISmsMessage> domMessage = new SmsMessageInternal(message);
|
||||
obs->NotifyObservers(domMessage, kSmsReceivedObserverTopic, nullptr);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
@ -84,28 +80,25 @@ SmsManager::NotifySmsSent(int32_t aId,
|
||||
message.deliveryTimestamp() = aTimestamp;
|
||||
message.read() = true;
|
||||
|
||||
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=]() {
|
||||
/*
|
||||
* First, we are going to notify all SmsManager that a message has
|
||||
* been sent. Then, we will notify the SmsRequest object about it.
|
||||
*/
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
if (!obs) {
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* First, we are going to notify all SmsManager that a message has
|
||||
* been sent. Then, we will notify the SmsRequest object about it.
|
||||
*/
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
if (!obs) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISmsMessage> domMessage = new SmsMessageInternal(message);
|
||||
obs->NotifyObservers(domMessage, kSmsSentObserverTopic, nullptr);
|
||||
nsCOMPtr<nsISmsMessage> domMessage = new SmsMessageInternal(message);
|
||||
obs->NotifyObservers(domMessage, kSmsSentObserverTopic, nullptr);
|
||||
|
||||
nsCOMPtr<nsIMobileMessageCallback> request =
|
||||
AndroidBridge::Bridge()->DequeueSmsRequest(aRequestId);
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIMobileMessageCallback> request =
|
||||
AndroidBridge::Bridge()->DequeueSmsRequest(aRequestId);
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
|
||||
request->NotifyMessageSent(domMessage);
|
||||
});
|
||||
NS_DispatchToMainThread(runnable);
|
||||
request->NotifyMessageSent(domMessage);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
@ -133,35 +126,29 @@ SmsManager::NotifySmsDelivery(int32_t aId,
|
||||
message.deliveryTimestamp() = aTimestamp;
|
||||
message.read() = true;
|
||||
|
||||
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=]() {
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
if (!obs) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
if (!obs) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISmsMessage> domMessage = new SmsMessageInternal(message);
|
||||
const char* topic = (message.deliveryStatus() == eDeliveryStatus_Success)
|
||||
? kSmsDeliverySuccessObserverTopic
|
||||
: kSmsDeliveryErrorObserverTopic;
|
||||
obs->NotifyObservers(domMessage, topic, nullptr);
|
||||
});
|
||||
NS_DispatchToMainThread(runnable);
|
||||
nsCOMPtr<nsISmsMessage> domMessage = new SmsMessageInternal(message);
|
||||
const char* topic = (message.deliveryStatus() == eDeliveryStatus_Success)
|
||||
? kSmsDeliverySuccessObserverTopic
|
||||
: kSmsDeliveryErrorObserverTopic;
|
||||
obs->NotifyObservers(domMessage, topic, nullptr);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void
|
||||
SmsManager::NotifySmsSendFailed(int32_t aError, int32_t aRequestId)
|
||||
{
|
||||
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=]() {
|
||||
nsCOMPtr<nsIMobileMessageCallback> request =
|
||||
AndroidBridge::Bridge()->DequeueSmsRequest(aRequestId);
|
||||
if(!request) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIMobileMessageCallback> request =
|
||||
AndroidBridge::Bridge()->DequeueSmsRequest(aRequestId);
|
||||
if(!request) {
|
||||
return;
|
||||
}
|
||||
|
||||
request->NotifySendMessageFailed(aError, nullptr);
|
||||
});
|
||||
NS_DispatchToMainThread(runnable);
|
||||
request->NotifySendMessageFailed(aError, nullptr);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
@ -196,83 +183,68 @@ SmsManager::NotifyGetSms(int32_t aId,
|
||||
message.deliveryTimestamp() = aTimestamp;
|
||||
message.read() = aRead;
|
||||
|
||||
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=]() {
|
||||
nsCOMPtr<nsIMobileMessageCallback> request =
|
||||
AndroidBridge::Bridge()->DequeueSmsRequest(aRequestId);
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIMobileMessageCallback> request =
|
||||
AndroidBridge::Bridge()->DequeueSmsRequest(aRequestId);
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISmsMessage> domMessage = new SmsMessageInternal(message);
|
||||
request->NotifyMessageGot(domMessage);
|
||||
});
|
||||
NS_DispatchToMainThread(runnable);
|
||||
nsCOMPtr<nsISmsMessage> domMessage = new SmsMessageInternal(message);
|
||||
request->NotifyMessageGot(domMessage);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void
|
||||
SmsManager::NotifyGetSmsFailed(int32_t aError, int32_t aRequestId)
|
||||
{
|
||||
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=]() {
|
||||
nsCOMPtr<nsIMobileMessageCallback> request =
|
||||
AndroidBridge::Bridge()->DequeueSmsRequest(aRequestId);
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIMobileMessageCallback> request =
|
||||
AndroidBridge::Bridge()->DequeueSmsRequest(aRequestId);
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
|
||||
request->NotifyGetMessageFailed(aError);
|
||||
});
|
||||
NS_DispatchToMainThread(runnable);
|
||||
request->NotifyGetMessageFailed(aError);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void
|
||||
SmsManager::NotifySmsDeleted(bool aDeleted, int32_t aRequestId)
|
||||
{
|
||||
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=]() {
|
||||
nsCOMPtr<nsIMobileMessageCallback> request =
|
||||
AndroidBridge::Bridge()->DequeueSmsRequest(aRequestId);
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIMobileMessageCallback> request =
|
||||
AndroidBridge::Bridge()->DequeueSmsRequest(aRequestId);
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
|
||||
// For android, we support only single SMS deletion.
|
||||
bool deleted = aDeleted;
|
||||
request->NotifyMessageDeleted(&deleted, 1);
|
||||
});
|
||||
NS_DispatchToMainThread(runnable);
|
||||
// For android, we support only single SMS deletion.
|
||||
bool deleted = aDeleted;
|
||||
request->NotifyMessageDeleted(&deleted, 1);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void
|
||||
SmsManager::NotifySmsDeleteFailed(int32_t aError, int32_t aRequestId)
|
||||
{
|
||||
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=]() {
|
||||
nsCOMPtr<nsIMobileMessageCallback> request =
|
||||
AndroidBridge::Bridge()->DequeueSmsRequest(aRequestId);
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIMobileMessageCallback> request =
|
||||
AndroidBridge::Bridge()->DequeueSmsRequest(aRequestId);
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
|
||||
request->NotifyDeleteMessageFailed(aError);
|
||||
});
|
||||
NS_DispatchToMainThread(runnable);
|
||||
request->NotifyDeleteMessageFailed(aError);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void
|
||||
SmsManager::NotifyCursorError(int32_t aError, int32_t aRequestId)
|
||||
{
|
||||
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=]() {
|
||||
nsCOMPtr<nsIMobileMessageCursorCallback> request =
|
||||
AndroidBridge::Bridge()->DequeueSmsCursorRequest(aRequestId);
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIMobileMessageCursorCallback> request =
|
||||
AndroidBridge::Bridge()->DequeueSmsCursorRequest(aRequestId);
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
|
||||
request->NotifyCursorError(aError);
|
||||
});
|
||||
NS_DispatchToMainThread(runnable);
|
||||
request->NotifyCursorError(aError);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
@ -296,7 +268,7 @@ SmsManager::NotifyThreadCursorResult(int64_t aId,
|
||||
thread.timestamp() = aTimestamp;
|
||||
thread.lastMessageType() = eMessageType_SMS;
|
||||
|
||||
JNIEnv* const env = jni::GetEnvForThread();
|
||||
JNIEnv* const env = jni::GetGeckoThreadEnv();
|
||||
|
||||
jobjectArray participants = aParticipants.Get();
|
||||
jsize length = env->GetArrayLength(participants);
|
||||
@ -305,27 +277,25 @@ SmsManager::NotifyThreadCursorResult(int64_t aId,
|
||||
static_cast<jstring>(env->GetObjectArrayElement(participants, i));
|
||||
if (participant) {
|
||||
thread.participants().AppendElement(nsJNIString(participant, env));
|
||||
env->DeleteLocalRef(participant);
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=]() {
|
||||
nsCOMPtr<nsIMobileMessageCursorCallback> request =
|
||||
AndroidBridge::Bridge()->GetSmsCursorRequest(aRequestId);
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIMobileMessageCursorCallback> request =
|
||||
AndroidBridge::Bridge()->GetSmsCursorRequest(aRequestId);
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMArray<nsIMobileMessageThread> arr;
|
||||
arr.AppendElement(new MobileMessageThreadInternal(thread));
|
||||
nsCOMArray<nsIMobileMessageThread> arr;
|
||||
arr.AppendElement(new MobileMessageThreadInternal(thread));
|
||||
|
||||
nsIMobileMessageThread** elements;
|
||||
int32_t size;
|
||||
size = arr.Forget(&elements);
|
||||
nsIMobileMessageThread** elements;
|
||||
int32_t size;
|
||||
size = arr.Forget(&elements);
|
||||
|
||||
request->NotifyCursorResult(reinterpret_cast<nsISupports**>(elements),
|
||||
size);
|
||||
});
|
||||
NS_DispatchToMainThread(runnable);
|
||||
request->NotifyCursorResult(reinterpret_cast<nsISupports**>(elements),
|
||||
size);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
@ -360,72 +330,60 @@ SmsManager::NotifyMessageCursorResult(int32_t aMessageId,
|
||||
message.deliveryTimestamp() = aTimestamp;
|
||||
message.read() = aRead;
|
||||
|
||||
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=]() {
|
||||
nsCOMPtr<nsIMobileMessageCursorCallback> request =
|
||||
AndroidBridge::Bridge()->GetSmsCursorRequest(aRequestId);
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIMobileMessageCursorCallback> request =
|
||||
AndroidBridge::Bridge()->GetSmsCursorRequest(aRequestId);
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMArray<nsISmsMessage> arr;
|
||||
arr.AppendElement(new SmsMessageInternal(message));
|
||||
nsCOMArray<nsISmsMessage> arr;
|
||||
arr.AppendElement(new SmsMessageInternal(message));
|
||||
|
||||
nsISmsMessage** elements;
|
||||
int32_t size;
|
||||
size = arr.Forget(&elements);
|
||||
nsISmsMessage** elements;
|
||||
int32_t size;
|
||||
size = arr.Forget(&elements);
|
||||
|
||||
request->NotifyCursorResult(reinterpret_cast<nsISupports**>(elements),
|
||||
size);
|
||||
});
|
||||
NS_DispatchToMainThread(runnable);
|
||||
request->NotifyCursorResult(reinterpret_cast<nsISupports**>(elements),
|
||||
size);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void
|
||||
SmsManager::NotifyCursorDone(int32_t aRequestId)
|
||||
{
|
||||
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=]() {
|
||||
nsCOMPtr<nsIMobileMessageCursorCallback> request =
|
||||
AndroidBridge::Bridge()->DequeueSmsCursorRequest(aRequestId);
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIMobileMessageCursorCallback> request =
|
||||
AndroidBridge::Bridge()->DequeueSmsCursorRequest(aRequestId);
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
|
||||
request->NotifyCursorDone();
|
||||
});
|
||||
NS_DispatchToMainThread(runnable);
|
||||
request->NotifyCursorDone();
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void
|
||||
SmsManager::NotifySmsMarkedAsRead(bool aMarkedAsRead, int32_t aRequestId)
|
||||
{
|
||||
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=]() {
|
||||
nsCOMPtr<nsIMobileMessageCallback> request =
|
||||
AndroidBridge::Bridge()->DequeueSmsRequest(aRequestId);
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIMobileMessageCallback> request =
|
||||
AndroidBridge::Bridge()->DequeueSmsRequest(aRequestId);
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
|
||||
request->NotifyMessageMarkedRead(aMarkedAsRead);
|
||||
});
|
||||
NS_DispatchToMainThread(runnable);
|
||||
request->NotifyMessageMarkedRead(aMarkedAsRead);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void
|
||||
SmsManager::NotifySmsMarkAsReadFailed(int32_t aError, int32_t aRequestId)
|
||||
{
|
||||
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=]() {
|
||||
nsCOMPtr<nsIMobileMessageCallback> request =
|
||||
AndroidBridge::Bridge()->DequeueSmsRequest(aRequestId);
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIMobileMessageCallback> request =
|
||||
AndroidBridge::Bridge()->DequeueSmsRequest(aRequestId);
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
|
||||
request->NotifyMarkMessageReadFailed(aError);
|
||||
});
|
||||
NS_DispatchToMainThread(runnable);
|
||||
request->NotifyMarkMessageReadFailed(aError);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -73,7 +73,7 @@
|
||||
#include "nsIDOMWindow.h"
|
||||
|
||||
#include "nsNetCID.h"
|
||||
#include "mozilla/Snprintf.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsIInputStreamTee.h"
|
||||
#include "nsQueryObject.h"
|
||||
|
@ -58,7 +58,7 @@ ContentVerifier::Init(const nsACString& aContentSignatureHeader,
|
||||
* Implement nsIStreamListener
|
||||
* We buffer the entire content here and kick off verification
|
||||
*/
|
||||
NS_METHOD
|
||||
nsresult
|
||||
AppendNextSegment(nsIInputStream* aInputStream, void* aClosure,
|
||||
const char* aRawSegment, uint32_t aToOffset, uint32_t aCount,
|
||||
uint32_t* outWrittenCount)
|
||||
|
@ -1375,7 +1375,7 @@ CSPViolationReportListener::~CSPViolationReportListener()
|
||||
{
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsresult
|
||||
AppendSegmentToString(nsIInputStream* aInputStream,
|
||||
void* aClosure,
|
||||
const char* aRawSegment,
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
#include "NetworkUtils.h"
|
||||
|
||||
#include "mozilla/Snprintf.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
#include "SystemProperty.h"
|
||||
|
||||
#include <android/log.h>
|
||||
@ -1175,11 +1175,11 @@ void NetworkUtils::setInterfaceDns(CommandChain* aChain,
|
||||
int written;
|
||||
|
||||
if (SDK_VERSION >= 20) {
|
||||
written = snprintf_literal(command, "resolver setnetdns %d %s",
|
||||
GET_FIELD(mNetId), GET_CHAR(mDomain));
|
||||
written = SprintfLiteral(command, "resolver setnetdns %d %s",
|
||||
GET_FIELD(mNetId), GET_CHAR(mDomain));
|
||||
} else {
|
||||
written = snprintf_literal(command, "resolver setifdns %s %s",
|
||||
GET_CHAR(mIfname), GET_CHAR(mDomain));
|
||||
written = SprintfLiteral(command, "resolver setifdns %s %s",
|
||||
GET_CHAR(mIfname), GET_CHAR(mDomain));
|
||||
}
|
||||
|
||||
nsTArray<nsString>& dnses = GET_FIELD(mDnses);
|
||||
@ -1957,7 +1957,7 @@ CommandResult NetworkUtils::setDNS(NetworkParams& aOptions)
|
||||
NS_ConvertUTF16toUTF8 autoDns(aOptions.mDnses[i]);
|
||||
|
||||
char dns_prop_key[Property::VALUE_MAX_LENGTH];
|
||||
snprintf_literal(dns_prop_key, "net.dns%d", i+1);
|
||||
SprintfLiteral(dns_prop_key, "net.dns%d", i+1);
|
||||
Property::Set(dns_prop_key, autoDns.get());
|
||||
}
|
||||
} else {
|
||||
|
@ -518,8 +518,6 @@ var interfaceNamesInGlobalScope =
|
||||
"History",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "HDMIInputPort", b2g: true, permission: ["inputport"]},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "HMDVRDevice", release: false},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"HTMLAllCollection",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
@ -944,8 +942,6 @@ var interfaceNamesInGlobalScope =
|
||||
"PopupBlockedEvent",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "PopupBoxObject", xbl: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "PositionSensorVRDevice", release: false},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "PresentationDeviceInfoManager",
|
||||
disabled: true,
|
||||
@ -1392,15 +1388,17 @@ var interfaceNamesInGlobalScope =
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"VideoStreamTrack",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "VRDevice", release: false},
|
||||
{name: "VRDisplay", release: false},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "VRPositionState", release: false},
|
||||
{name: "VRDisplayCapabilities", release: false},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "VREyeParameters", release: false},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "VRFieldOfView", release: false},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "VRFieldOfViewReadOnly", release: false},
|
||||
{name: "VRPose", release: false},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "VRStageParameters", release: false},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"VTTCue",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
@ -1,367 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/VRDeviceBinding.h"
|
||||
#include "mozilla/dom/ElementBinding.h"
|
||||
#include "mozilla/dom/VRDevice.h"
|
||||
#include "Navigator.h"
|
||||
#include "gfxVR.h"
|
||||
#include "VRDeviceProxy.h"
|
||||
#include "VRManagerChild.h"
|
||||
#include "nsIFrame.h"
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
/*static*/ bool
|
||||
VRDevice::RefreshVRDevices(dom::Navigator* aNavigator)
|
||||
{
|
||||
gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
|
||||
return vm && vm->RefreshVRDevicesWithCallback(aNavigator);
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
VRDevice::UpdateVRDevices(nsTArray<RefPtr<VRDevice>>& aDevices, nsISupports* aParent)
|
||||
{
|
||||
nsTArray<RefPtr<VRDevice>> devices;
|
||||
|
||||
gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
|
||||
nsTArray<RefPtr<gfx::VRDeviceProxy>> proxyDevices;
|
||||
if (vm && vm->GetVRDevices(proxyDevices)) {
|
||||
for (size_t i = 0; i < proxyDevices.Length(); i++) {
|
||||
RefPtr<gfx::VRDeviceProxy> proxyDevice = proxyDevices[i];
|
||||
bool isNewDevice = true;
|
||||
for (size_t j = 0; j < aDevices.Length(); j++) {
|
||||
if (aDevices[j]->GetHMD()->GetDeviceInfo() == proxyDevice->GetDeviceInfo()) {
|
||||
devices.AppendElement(aDevices[j]);
|
||||
isNewDevice = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isNewDevice) {
|
||||
gfx::VRStateValidFlags sensorBits = proxyDevice->GetDeviceInfo().GetSupportedSensorStateBits();
|
||||
devices.AppendElement(new HMDInfoVRDevice(aParent, proxyDevice));
|
||||
if (sensorBits & (gfx::VRStateValidFlags::State_Position |
|
||||
gfx::VRStateValidFlags::State_Orientation))
|
||||
{
|
||||
devices.AppendElement(new HMDPositionVRDevice(aParent, proxyDevice));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aDevices = devices;
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(VRFieldOfViewReadOnly, mParent)
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRFieldOfViewReadOnly, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRFieldOfViewReadOnly, Release)
|
||||
|
||||
JSObject*
|
||||
VRFieldOfViewReadOnly::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return VRFieldOfViewReadOnlyBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
already_AddRefed<VRFieldOfView>
|
||||
VRFieldOfView::Constructor(const GlobalObject& aGlobal, const VRFieldOfViewInit& aParams,
|
||||
ErrorResult& aRV)
|
||||
{
|
||||
RefPtr<VRFieldOfView> fov =
|
||||
new VRFieldOfView(aGlobal.GetAsSupports(),
|
||||
aParams.mUpDegrees, aParams.mRightDegrees,
|
||||
aParams.mDownDegrees, aParams.mLeftDegrees);
|
||||
return fov.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<VRFieldOfView>
|
||||
VRFieldOfView::Constructor(const GlobalObject& aGlobal,
|
||||
double aUpDegrees, double aRightDegrees,
|
||||
double aDownDegrees, double aLeftDegrees,
|
||||
ErrorResult& aRV)
|
||||
{
|
||||
RefPtr<VRFieldOfView> fov =
|
||||
new VRFieldOfView(aGlobal.GetAsSupports(),
|
||||
aUpDegrees, aRightDegrees, aDownDegrees,
|
||||
aLeftDegrees);
|
||||
return fov.forget();
|
||||
}
|
||||
|
||||
JSObject*
|
||||
VRFieldOfView::WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return VRFieldOfViewBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(VREyeParameters, mParent, mMinFOV, mMaxFOV, mRecFOV, mCurFOV, mEyeTranslation, mRenderRect)
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VREyeParameters, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VREyeParameters, Release)
|
||||
|
||||
VREyeParameters::VREyeParameters(nsISupports* aParent,
|
||||
const gfx::VRFieldOfView& aMinFOV,
|
||||
const gfx::VRFieldOfView& aMaxFOV,
|
||||
const gfx::VRFieldOfView& aRecFOV,
|
||||
const gfx::Point3D& aEyeTranslation,
|
||||
const gfx::VRFieldOfView& aCurFOV,
|
||||
const gfx::IntRect& aRenderRect)
|
||||
: mParent(aParent)
|
||||
{
|
||||
mMinFOV = new VRFieldOfView(aParent, aMinFOV);
|
||||
mMaxFOV = new VRFieldOfView(aParent, aMaxFOV);
|
||||
mRecFOV = new VRFieldOfView(aParent, aRecFOV);
|
||||
mCurFOV = new VRFieldOfView(aParent, aCurFOV);
|
||||
|
||||
mEyeTranslation = new DOMPoint(aParent, aEyeTranslation.x, aEyeTranslation.y, aEyeTranslation.z, 0.0);
|
||||
mRenderRect = new DOMRect(aParent, aRenderRect.x, aRenderRect.y, aRenderRect.width, aRenderRect.height);
|
||||
}
|
||||
|
||||
VRFieldOfView*
|
||||
VREyeParameters::MinimumFieldOfView()
|
||||
{
|
||||
return mMinFOV;
|
||||
}
|
||||
|
||||
VRFieldOfView*
|
||||
VREyeParameters::MaximumFieldOfView()
|
||||
{
|
||||
return mMaxFOV;
|
||||
}
|
||||
|
||||
VRFieldOfView*
|
||||
VREyeParameters::RecommendedFieldOfView()
|
||||
{
|
||||
return mRecFOV;
|
||||
}
|
||||
|
||||
VRFieldOfView*
|
||||
VREyeParameters::CurrentFieldOfView()
|
||||
{
|
||||
return mCurFOV;
|
||||
}
|
||||
|
||||
DOMPoint*
|
||||
VREyeParameters::EyeTranslation()
|
||||
{
|
||||
return mEyeTranslation;
|
||||
}
|
||||
|
||||
DOMRect*
|
||||
VREyeParameters::RenderRect()
|
||||
{
|
||||
return mRenderRect;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
VREyeParameters::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return VREyeParametersBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(VRPositionState, mParent)
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRPositionState, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRPositionState, Release)
|
||||
|
||||
VRPositionState::VRPositionState(nsISupports* aParent, const gfx::VRHMDSensorState& aState)
|
||||
: mParent(aParent)
|
||||
, mVRState(aState)
|
||||
{
|
||||
mTimeStamp = aState.timestamp;
|
||||
|
||||
if (aState.flags & gfx::VRStateValidFlags::State_Position) {
|
||||
mPosition = new DOMPoint(mParent, aState.position[0], aState.position[1], aState.position[2], 0.0);
|
||||
}
|
||||
|
||||
if (aState.flags & gfx::VRStateValidFlags::State_Orientation) {
|
||||
mOrientation = new DOMPoint(mParent, aState.orientation[0], aState.orientation[1], aState.orientation[2], aState.orientation[3]);
|
||||
}
|
||||
}
|
||||
|
||||
DOMPoint*
|
||||
VRPositionState::GetLinearVelocity()
|
||||
{
|
||||
if (!mLinearVelocity) {
|
||||
mLinearVelocity = new DOMPoint(mParent, mVRState.linearVelocity[0], mVRState.linearVelocity[1], mVRState.linearVelocity[2], 0.0);
|
||||
}
|
||||
return mLinearVelocity;
|
||||
}
|
||||
|
||||
DOMPoint*
|
||||
VRPositionState::GetLinearAcceleration()
|
||||
{
|
||||
if (!mLinearAcceleration) {
|
||||
mLinearAcceleration = new DOMPoint(mParent, mVRState.linearAcceleration[0], mVRState.linearAcceleration[1], mVRState.linearAcceleration[2], 0.0);
|
||||
}
|
||||
return mLinearAcceleration;
|
||||
}
|
||||
|
||||
DOMPoint*
|
||||
VRPositionState::GetAngularVelocity()
|
||||
{
|
||||
if (!mAngularVelocity) {
|
||||
mAngularVelocity = new DOMPoint(mParent, mVRState.angularVelocity[0], mVRState.angularVelocity[1], mVRState.angularVelocity[2], 0.0);
|
||||
}
|
||||
return mAngularVelocity;
|
||||
}
|
||||
|
||||
DOMPoint*
|
||||
VRPositionState::GetAngularAcceleration()
|
||||
{
|
||||
if (!mAngularAcceleration) {
|
||||
mAngularAcceleration = new DOMPoint(mParent, mVRState.angularAcceleration[0], mVRState.angularAcceleration[1], mVRState.angularAcceleration[2], 0.0);
|
||||
}
|
||||
return mAngularAcceleration;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
VRPositionState::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return VRPositionStateBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(VRDevice)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(VRDevice)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(VRDevice)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(VRDevice, mParent)
|
||||
|
||||
/* virtual */ JSObject*
|
||||
HMDVRDevice::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return HMDVRDeviceBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
/* virtual */ JSObject*
|
||||
PositionSensorVRDevice::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return PositionSensorVRDeviceBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
HMDInfoVRDevice::HMDInfoVRDevice(nsISupports* aParent, gfx::VRDeviceProxy* aHMD)
|
||||
: HMDVRDevice(aParent, aHMD)
|
||||
{
|
||||
MOZ_COUNT_CTOR_INHERITED(HMDInfoVRDevice, HMDVRDevice);
|
||||
uint64_t hmdid = aHMD->GetDeviceInfo().GetDeviceID() << 8;
|
||||
uint64_t devid = hmdid | 0x00; // we generate a devid with low byte 0 for the HMD, 1 for the position sensor
|
||||
|
||||
mHWID.Truncate();
|
||||
mHWID.AppendPrintf("0x%llx", hmdid);
|
||||
|
||||
mDeviceId.Truncate();
|
||||
mDeviceId.AppendPrintf("0x%llx", devid);
|
||||
|
||||
mDeviceName.Truncate();
|
||||
mDeviceName.Append(NS_ConvertASCIItoUTF16(aHMD->GetDeviceInfo().GetDeviceName()));
|
||||
mDeviceName.AppendLiteral(" (HMD)");
|
||||
|
||||
mValid = true;
|
||||
}
|
||||
|
||||
HMDInfoVRDevice::~HMDInfoVRDevice()
|
||||
{
|
||||
MOZ_COUNT_DTOR_INHERITED(HMDInfoVRDevice, HMDVRDevice);
|
||||
}
|
||||
|
||||
/* If a field of view that is set to all 0's is passed in,
|
||||
* the recommended field of view for that eye is used.
|
||||
*/
|
||||
void
|
||||
HMDInfoVRDevice::SetFieldOfView(const VRFieldOfViewInit& aLeftFOV,
|
||||
const VRFieldOfViewInit& aRightFOV,
|
||||
double zNear, double zFar)
|
||||
{
|
||||
gfx::VRFieldOfView left = gfx::VRFieldOfView(aLeftFOV.mUpDegrees, aLeftFOV.mRightDegrees,
|
||||
aLeftFOV.mDownDegrees, aLeftFOV.mLeftDegrees);
|
||||
gfx::VRFieldOfView right = gfx::VRFieldOfView(aRightFOV.mUpDegrees, aRightFOV.mRightDegrees,
|
||||
aRightFOV.mDownDegrees, aRightFOV.mLeftDegrees);
|
||||
|
||||
if (left.IsZero()) {
|
||||
left = mHMD->GetDeviceInfo().GetRecommendedEyeFOV(VRDeviceInfo::Eye_Left);
|
||||
}
|
||||
|
||||
if (right.IsZero()) {
|
||||
right = mHMD->GetDeviceInfo().GetRecommendedEyeFOV(VRDeviceInfo::Eye_Right);
|
||||
}
|
||||
|
||||
mHMD->SetFOV(left, right, zNear, zFar);
|
||||
}
|
||||
|
||||
already_AddRefed<VREyeParameters> HMDInfoVRDevice::GetEyeParameters(VREye aEye)
|
||||
{
|
||||
gfx::IntSize sz(mHMD->GetDeviceInfo().SuggestedEyeResolution());
|
||||
gfx::VRDeviceInfo::Eye eye = aEye == VREye::Left ? gfx::VRDeviceInfo::Eye_Left : gfx::VRDeviceInfo::Eye_Right;
|
||||
RefPtr<VREyeParameters> params =
|
||||
new VREyeParameters(mParent,
|
||||
gfx::VRFieldOfView(15, 15, 15, 15), // XXX min?
|
||||
mHMD->GetDeviceInfo().GetMaximumEyeFOV(eye),
|
||||
mHMD->GetDeviceInfo().GetRecommendedEyeFOV(eye),
|
||||
mHMD->GetDeviceInfo().GetEyeTranslation(eye),
|
||||
mHMD->GetDeviceInfo().GetEyeFOV(eye),
|
||||
gfx::IntRect((aEye == VREye::Left) ? 0 : sz.width, 0, sz.width, sz.height));
|
||||
return params.forget();
|
||||
}
|
||||
|
||||
HMDPositionVRDevice::HMDPositionVRDevice(nsISupports* aParent, gfx::VRDeviceProxy* aHMD)
|
||||
: PositionSensorVRDevice(aParent, aHMD)
|
||||
{
|
||||
MOZ_COUNT_CTOR_INHERITED(HMDPositionVRDevice, PositionSensorVRDevice);
|
||||
|
||||
uint64_t hmdid = aHMD->GetDeviceInfo().GetDeviceID() << 8;
|
||||
uint64_t devid = hmdid | 0x01; // we generate a devid with low byte 0 for the HMD, 1 for the position sensor
|
||||
|
||||
mHWID.Truncate();
|
||||
mHWID.AppendPrintf("0x%llx", hmdid);
|
||||
|
||||
mDeviceId.Truncate();
|
||||
mDeviceId.AppendPrintf("0x%llx", devid);
|
||||
|
||||
mDeviceName.Truncate();
|
||||
mDeviceName.Append(NS_ConvertASCIItoUTF16(aHMD->GetDeviceInfo().GetDeviceName()));
|
||||
mDeviceName.AppendLiteral(" (Sensor)");
|
||||
|
||||
mValid = true;
|
||||
}
|
||||
|
||||
HMDPositionVRDevice::~HMDPositionVRDevice()
|
||||
{
|
||||
MOZ_COUNT_DTOR_INHERITED(HMDPositionVRDevice, PositionSensorVRDevice);
|
||||
}
|
||||
|
||||
already_AddRefed<VRPositionState>
|
||||
HMDPositionVRDevice::GetState()
|
||||
{
|
||||
gfx::VRHMDSensorState state = mHMD->GetSensorState();
|
||||
RefPtr<VRPositionState> obj = new VRPositionState(mParent, state);
|
||||
|
||||
return obj.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<VRPositionState>
|
||||
HMDPositionVRDevice::GetImmediateState()
|
||||
{
|
||||
gfx::VRHMDSensorState state = mHMD->GetImmediateSensorState();
|
||||
RefPtr<VRPositionState> obj = new VRPositionState(mParent, state);
|
||||
|
||||
return obj.forget();
|
||||
}
|
||||
|
||||
void
|
||||
HMDPositionVRDevice::ResetSensor()
|
||||
{
|
||||
mHMD->ZeroSensor();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
@ -1,317 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef mozilla_dom_VRDevice_h_
|
||||
#define mozilla_dom_VRDevice_h_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/TypedArray.h"
|
||||
#include "mozilla/dom/VRDeviceBinding.h"
|
||||
#include "mozilla/dom/DOMPoint.h"
|
||||
#include "mozilla/dom/DOMRect.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
#include "gfxVR.h"
|
||||
#include "VRDeviceProxy.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class Navigator;
|
||||
|
||||
class VRFieldOfViewReadOnly : public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
VRFieldOfViewReadOnly(nsISupports* aParent,
|
||||
double aUpDegrees, double aRightDegrees,
|
||||
double aDownDegrees, double aLeftDegrees)
|
||||
: mParent(aParent)
|
||||
, mUpDegrees(aUpDegrees)
|
||||
, mRightDegrees(aRightDegrees)
|
||||
, mDownDegrees(aDownDegrees)
|
||||
, mLeftDegrees(aLeftDegrees)
|
||||
{
|
||||
}
|
||||
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRFieldOfViewReadOnly)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRFieldOfViewReadOnly)
|
||||
|
||||
double UpDegrees() const { return mUpDegrees; }
|
||||
double RightDegrees() const { return mRightDegrees; }
|
||||
double DownDegrees() const { return mDownDegrees; }
|
||||
double LeftDegrees() const { return mLeftDegrees; }
|
||||
|
||||
nsISupports* GetParentObject() const { return mParent; }
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
protected:
|
||||
virtual ~VRFieldOfViewReadOnly() {}
|
||||
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
|
||||
double mUpDegrees;
|
||||
double mRightDegrees;
|
||||
double mDownDegrees;
|
||||
double mLeftDegrees;
|
||||
};
|
||||
|
||||
class VRFieldOfView final : public VRFieldOfViewReadOnly
|
||||
{
|
||||
public:
|
||||
VRFieldOfView(nsISupports* aParent, const gfx::VRFieldOfView& aSrc)
|
||||
: VRFieldOfViewReadOnly(aParent,
|
||||
aSrc.upDegrees, aSrc.rightDegrees,
|
||||
aSrc.downDegrees, aSrc.leftDegrees)
|
||||
{}
|
||||
|
||||
explicit VRFieldOfView(nsISupports* aParent,
|
||||
double aUpDegrees = 0.0, double aRightDegrees = 0.0,
|
||||
double aDownDegrees = 0.0, double aLeftDegrees = 0.0)
|
||||
: VRFieldOfViewReadOnly(aParent,
|
||||
aUpDegrees, aRightDegrees, aDownDegrees, aLeftDegrees)
|
||||
{}
|
||||
|
||||
static already_AddRefed<VRFieldOfView>
|
||||
Constructor(const GlobalObject& aGlobal, const VRFieldOfViewInit& aParams,
|
||||
ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<VRFieldOfView>
|
||||
Constructor(const GlobalObject& aGlobal,
|
||||
double aUpDegrees, double aRightDegrees,
|
||||
double aDownDegrees, double aLeftDegrees,
|
||||
ErrorResult& aRv);
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
void SetUpDegrees(double aVal) { mUpDegrees = aVal; }
|
||||
void SetRightDegrees(double aVal) { mRightDegrees = aVal; }
|
||||
void SetDownDegrees(double aVal) { mDownDegrees = aVal; }
|
||||
void SetLeftDegrees(double aVal) { mLeftDegrees = aVal; }
|
||||
};
|
||||
|
||||
class VRPositionState final : public nsWrapperCache
|
||||
{
|
||||
~VRPositionState() {}
|
||||
public:
|
||||
VRPositionState(nsISupports* aParent, const gfx::VRHMDSensorState& aState);
|
||||
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRPositionState)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRPositionState)
|
||||
|
||||
double TimeStamp() const { return mTimeStamp; }
|
||||
|
||||
bool HasPosition() const { return mPosition != nullptr; }
|
||||
DOMPoint* GetPosition() const { return mPosition; }
|
||||
|
||||
bool HasOrientation() const { return mOrientation != nullptr; }
|
||||
DOMPoint* GetOrientation() const { return mOrientation; }
|
||||
|
||||
// these are created lazily
|
||||
DOMPoint* GetLinearVelocity();
|
||||
DOMPoint* GetLinearAcceleration();
|
||||
DOMPoint* GetAngularVelocity();
|
||||
DOMPoint* GetAngularAcceleration();
|
||||
|
||||
nsISupports* GetParentObject() const { return mParent; }
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
|
||||
double mTimeStamp;
|
||||
gfx::VRHMDSensorState mVRState;
|
||||
|
||||
RefPtr<DOMPoint> mPosition;
|
||||
RefPtr<DOMPoint> mLinearVelocity;
|
||||
RefPtr<DOMPoint> mLinearAcceleration;
|
||||
|
||||
RefPtr<DOMPoint> mOrientation;
|
||||
RefPtr<DOMPoint> mAngularVelocity;
|
||||
RefPtr<DOMPoint> mAngularAcceleration;
|
||||
};
|
||||
|
||||
class VREyeParameters final : public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
VREyeParameters(nsISupports* aParent,
|
||||
const gfx::VRFieldOfView& aMinFOV,
|
||||
const gfx::VRFieldOfView& aMaxFOV,
|
||||
const gfx::VRFieldOfView& aRecFOV,
|
||||
const gfx::Point3D& aEyeTranslation,
|
||||
const gfx::VRFieldOfView& aCurFOV,
|
||||
const gfx::IntRect& aRenderRect);
|
||||
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VREyeParameters)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VREyeParameters)
|
||||
|
||||
VRFieldOfView* MinimumFieldOfView();
|
||||
VRFieldOfView* MaximumFieldOfView();
|
||||
VRFieldOfView* RecommendedFieldOfView();
|
||||
DOMPoint* EyeTranslation();
|
||||
|
||||
VRFieldOfView* CurrentFieldOfView();
|
||||
DOMRect* RenderRect();
|
||||
|
||||
nsISupports* GetParentObject() const { return mParent; }
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
protected:
|
||||
~VREyeParameters() {}
|
||||
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
|
||||
RefPtr<VRFieldOfView> mMinFOV;
|
||||
RefPtr<VRFieldOfView> mMaxFOV;
|
||||
RefPtr<VRFieldOfView> mRecFOV;
|
||||
RefPtr<DOMPoint> mEyeTranslation;
|
||||
RefPtr<VRFieldOfView> mCurFOV;
|
||||
RefPtr<DOMRect> mRenderRect;
|
||||
};
|
||||
|
||||
class VRDevice : public nsISupports,
|
||||
public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(VRDevice)
|
||||
|
||||
void GetHardwareUnitId(nsAString& aHWID) const { aHWID = mHWID; }
|
||||
void GetDeviceId(nsAString& aDeviceId) const { aDeviceId = mDeviceId; }
|
||||
void GetDeviceName(nsAString& aDeviceName) const { aDeviceName = mDeviceName; }
|
||||
|
||||
bool IsValid() { return mValid; }
|
||||
|
||||
nsISupports* GetParentObject() const
|
||||
{
|
||||
return mParent;
|
||||
}
|
||||
|
||||
enum VRDeviceType {
|
||||
HMD,
|
||||
PositionSensor
|
||||
};
|
||||
|
||||
VRDeviceType GetType() const { return mType; }
|
||||
|
||||
static bool RefreshVRDevices(dom::Navigator* aNavigator);
|
||||
static void UpdateVRDevices(nsTArray<RefPtr<VRDevice> >& aDevices,
|
||||
nsISupports* aParent);
|
||||
|
||||
gfx::VRDeviceProxy *GetHMD() {
|
||||
return mHMD;
|
||||
}
|
||||
|
||||
protected:
|
||||
VRDevice(nsISupports* aParent,
|
||||
gfx::VRDeviceProxy* aHMD,
|
||||
VRDeviceType aType)
|
||||
: mParent(aParent)
|
||||
, mHMD(aHMD)
|
||||
, mType(aType)
|
||||
, mValid(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(VRDevice);
|
||||
mHWID.AssignLiteral("uknown");
|
||||
mDeviceId.AssignLiteral("unknown");
|
||||
mDeviceName.AssignLiteral("unknown");
|
||||
}
|
||||
|
||||
virtual ~VRDevice()
|
||||
{
|
||||
MOZ_COUNT_DTOR(VRDevice);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
RefPtr<gfx::VRDeviceProxy> mHMD;
|
||||
nsString mHWID;
|
||||
nsString mDeviceId;
|
||||
nsString mDeviceName;
|
||||
|
||||
VRDeviceType mType;
|
||||
|
||||
bool mValid;
|
||||
};
|
||||
|
||||
class HMDVRDevice : public VRDevice
|
||||
{
|
||||
public:
|
||||
virtual already_AddRefed<VREyeParameters> GetEyeParameters(VREye aEye) = 0;
|
||||
|
||||
virtual void SetFieldOfView(const VRFieldOfViewInit& aLeftFOV,
|
||||
const VRFieldOfViewInit& aRightFOV,
|
||||
double zNear, double zFar) = 0;
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
protected:
|
||||
HMDVRDevice(nsISupports* aParent, gfx::VRDeviceProxy* aHMD)
|
||||
: VRDevice(aParent, aHMD, VRDevice::HMD)
|
||||
{
|
||||
MOZ_COUNT_CTOR_INHERITED(HMDVRDevice, VRDevice);
|
||||
}
|
||||
|
||||
virtual ~HMDVRDevice()
|
||||
{
|
||||
MOZ_COUNT_DTOR_INHERITED(HMDVRDevice, VRDevice);
|
||||
}
|
||||
};
|
||||
|
||||
class HMDInfoVRDevice : public HMDVRDevice
|
||||
{
|
||||
public:
|
||||
HMDInfoVRDevice(nsISupports* aParent, gfx::VRDeviceProxy* aHMD);
|
||||
virtual ~HMDInfoVRDevice();
|
||||
|
||||
/* If a field of view that is set to all 0's is passed in,
|
||||
* the recommended field of view for that eye is used.
|
||||
*/
|
||||
virtual void SetFieldOfView(const VRFieldOfViewInit& aLeftFOV,
|
||||
const VRFieldOfViewInit& aRightFOV,
|
||||
double zNear, double zFar) override;
|
||||
virtual already_AddRefed<VREyeParameters> GetEyeParameters(VREye aEye) override;
|
||||
};
|
||||
|
||||
class PositionSensorVRDevice : public VRDevice
|
||||
{
|
||||
public:
|
||||
virtual already_AddRefed<VRPositionState> GetState() = 0;
|
||||
virtual already_AddRefed<VRPositionState> GetImmediateState() = 0;
|
||||
virtual void ResetSensor() = 0;
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
protected:
|
||||
explicit PositionSensorVRDevice(nsISupports* aParent, gfx::VRDeviceProxy* aHMD)
|
||||
: VRDevice(aParent, aHMD, VRDevice::PositionSensor)
|
||||
{
|
||||
MOZ_COUNT_CTOR_INHERITED(PositionSensorVRDevice, VRDevice);
|
||||
}
|
||||
|
||||
virtual ~PositionSensorVRDevice()
|
||||
{
|
||||
MOZ_COUNT_DTOR_INHERITED(PositionSensorVRDevice, VRDevice);
|
||||
}
|
||||
};
|
||||
|
||||
class HMDPositionVRDevice : public PositionSensorVRDevice
|
||||
{
|
||||
public:
|
||||
HMDPositionVRDevice(nsISupports* aParent, gfx::VRDeviceProxy* aHMD);
|
||||
~HMDPositionVRDevice();
|
||||
|
||||
virtual already_AddRefed<VRPositionState> GetState() override;
|
||||
virtual already_AddRefed<VRPositionState> GetImmediateState() override;
|
||||
virtual void ResetSensor() override;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
629
dom/vr/VRDisplay.cpp
Normal file
629
dom/vr/VRDisplay.cpp
Normal file
@ -0,0 +1,629 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/VRDisplayBinding.h"
|
||||
#include "mozilla/dom/ElementBinding.h"
|
||||
#include "mozilla/dom/VRDisplay.h"
|
||||
#include "Navigator.h"
|
||||
#include "gfxVR.h"
|
||||
#include "VRDisplayClient.h"
|
||||
#include "VRManagerChild.h"
|
||||
#include "VRDisplayPresentation.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
VRFieldOfView::VRFieldOfView(nsISupports* aParent,
|
||||
double aUpDegrees, double aRightDegrees,
|
||||
double aDownDegrees, double aLeftDegrees)
|
||||
: mParent(aParent)
|
||||
, mUpDegrees(aUpDegrees)
|
||||
, mRightDegrees(aRightDegrees)
|
||||
, mDownDegrees(aDownDegrees)
|
||||
, mLeftDegrees(aLeftDegrees)
|
||||
{
|
||||
}
|
||||
|
||||
VRFieldOfView::VRFieldOfView(nsISupports* aParent, const gfx::VRFieldOfView& aSrc)
|
||||
: mParent(aParent)
|
||||
, mUpDegrees(aSrc.upDegrees)
|
||||
, mRightDegrees(aSrc.rightDegrees)
|
||||
, mDownDegrees(aSrc.downDegrees)
|
||||
, mLeftDegrees(aSrc.leftDegrees)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
VRDisplayCapabilities::HasPosition() const
|
||||
{
|
||||
return bool(mFlags & gfx::VRDisplayCapabilityFlags::Cap_Position);
|
||||
}
|
||||
|
||||
bool
|
||||
VRDisplayCapabilities::HasOrientation() const
|
||||
{
|
||||
return bool(mFlags & gfx::VRDisplayCapabilityFlags::Cap_Orientation);
|
||||
}
|
||||
|
||||
bool
|
||||
VRDisplayCapabilities::HasExternalDisplay() const
|
||||
{
|
||||
return bool(mFlags & gfx::VRDisplayCapabilityFlags::Cap_External);
|
||||
}
|
||||
|
||||
bool
|
||||
VRDisplayCapabilities::CanPresent() const
|
||||
{
|
||||
return bool(mFlags & gfx::VRDisplayCapabilityFlags::Cap_Present);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
VRDisplayCapabilities::MaxLayers() const
|
||||
{
|
||||
return CanPresent() ? 1 : 0;
|
||||
}
|
||||
|
||||
/*static*/ bool
|
||||
VRDisplay::RefreshVRDisplays(dom::Navigator* aNavigator)
|
||||
{
|
||||
gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
|
||||
return vm && vm->RefreshVRDisplaysWithCallback(aNavigator);
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
VRDisplay::UpdateVRDisplays(nsTArray<RefPtr<VRDisplay>>& aDisplays, nsPIDOMWindowInner* aWindow)
|
||||
{
|
||||
nsTArray<RefPtr<VRDisplay>> displays;
|
||||
|
||||
gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
|
||||
nsTArray<RefPtr<gfx::VRDisplayClient>> updatedDisplays;
|
||||
if (vm && vm->GetVRDisplays(updatedDisplays)) {
|
||||
for (size_t i = 0; i < updatedDisplays.Length(); i++) {
|
||||
RefPtr<gfx::VRDisplayClient> display = updatedDisplays[i];
|
||||
bool isNewDisplay = true;
|
||||
for (size_t j = 0; j < aDisplays.Length(); j++) {
|
||||
if (aDisplays[j]->GetClient()->GetDisplayInfo() == display->GetDisplayInfo()) {
|
||||
displays.AppendElement(aDisplays[j]);
|
||||
isNewDisplay = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isNewDisplay) {
|
||||
displays.AppendElement(new VRDisplay(aWindow, display));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aDisplays = displays;
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(VRFieldOfView, mParent)
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRFieldOfView, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRFieldOfView, Release)
|
||||
|
||||
|
||||
JSObject*
|
||||
VRFieldOfView::WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return VRFieldOfViewBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(VREyeParameters)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(VREyeParameters)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent, mFOV)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
tmp->mOffset = nullptr;
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(VREyeParameters)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent, mFOV)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(VREyeParameters)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mOffset)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VREyeParameters, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VREyeParameters, Release)
|
||||
|
||||
VREyeParameters::VREyeParameters(nsISupports* aParent,
|
||||
const gfx::Point3D& aEyeTranslation,
|
||||
const gfx::VRFieldOfView& aFOV,
|
||||
const gfx::IntSize& aRenderSize)
|
||||
: mParent(aParent)
|
||||
, mEyeTranslation(aEyeTranslation)
|
||||
, mRenderSize(aRenderSize)
|
||||
{
|
||||
mFOV = new VRFieldOfView(aParent, aFOV);
|
||||
}
|
||||
|
||||
VRFieldOfView*
|
||||
VREyeParameters::FieldOfView()
|
||||
{
|
||||
return mFOV;
|
||||
}
|
||||
|
||||
void
|
||||
VREyeParameters::GetOffset(JSContext* aCx, JS::MutableHandle<JSObject*> aRetval, ErrorResult& aRv)
|
||||
{
|
||||
if (!mOffset) {
|
||||
// Lazily create the Float32Array
|
||||
mOffset = dom::Float32Array::Create(aCx, this, 3, mEyeTranslation.components);
|
||||
if (!mOffset) {
|
||||
aRv.NoteJSContextException(aCx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
JS::ExposeObjectToActiveJS(mOffset);
|
||||
aRetval.set(mOffset);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
VREyeParameters::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return VREyeParametersBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
VRStageParameters::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return VRStageParametersBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(VRStageParameters)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(VRStageParameters)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
tmp->mSittingToStandingTransformArray = nullptr;
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(VRStageParameters)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(VRStageParameters)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mSittingToStandingTransformArray)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRStageParameters, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRStageParameters, Release)
|
||||
|
||||
void
|
||||
VRStageParameters::GetSittingToStandingTransform(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (!mSittingToStandingTransformArray) {
|
||||
// Lazily create the Float32Array
|
||||
mSittingToStandingTransformArray = dom::Float32Array::Create(aCx, this, 16,
|
||||
mSittingToStandingTransform.components);
|
||||
if (!mSittingToStandingTransformArray) {
|
||||
aRv.NoteJSContextException(aCx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
JS::ExposeObjectToActiveJS(mSittingToStandingTransformArray);
|
||||
aRetval.set(mSittingToStandingTransformArray);
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(VRDisplayCapabilities, mParent)
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRDisplayCapabilities, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRDisplayCapabilities, Release)
|
||||
|
||||
JSObject*
|
||||
VRDisplayCapabilities::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return VRDisplayCapabilitiesBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(VRPose)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(VRPose)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
tmp->mPosition = nullptr;
|
||||
tmp->mLinearVelocity = nullptr;
|
||||
tmp->mLinearAcceleration = nullptr;
|
||||
tmp->mOrientation = nullptr;
|
||||
tmp->mAngularVelocity = nullptr;
|
||||
tmp->mAngularAcceleration = nullptr;
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(VRPose)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(VRPose)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mPosition)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mLinearVelocity)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mLinearAcceleration)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mOrientation)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mAngularVelocity)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mAngularAcceleration)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRPose, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRPose, Release)
|
||||
|
||||
VRPose::VRPose(nsISupports* aParent, const gfx::VRHMDSensorState& aState)
|
||||
: mParent(aParent)
|
||||
, mVRState(aState)
|
||||
, mPosition(nullptr)
|
||||
, mLinearVelocity(nullptr)
|
||||
, mLinearAcceleration(nullptr)
|
||||
, mOrientation(nullptr)
|
||||
, mAngularVelocity(nullptr)
|
||||
, mAngularAcceleration(nullptr)
|
||||
{
|
||||
mTimeStamp = aState.timestamp * 1000.0f; // Converting from seconds to ms
|
||||
mFrameId = aState.inputFrameID;
|
||||
}
|
||||
|
||||
void
|
||||
VRPose::GetPosition(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (!mPosition && mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Position) {
|
||||
// Lazily create the Float32Array
|
||||
mPosition = dom::Float32Array::Create(aCx, this, 3, mVRState.position);
|
||||
if (!mPosition) {
|
||||
aRv.NoteJSContextException(aCx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (mPosition) {
|
||||
JS::ExposeObjectToActiveJS(mPosition);
|
||||
}
|
||||
aRetval.set(mPosition);
|
||||
}
|
||||
|
||||
void
|
||||
VRPose::GetLinearVelocity(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (!mLinearVelocity && mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Position) {
|
||||
// Lazily create the Float32Array
|
||||
mLinearVelocity = dom::Float32Array::Create(aCx, this, 3, mVRState.linearVelocity);
|
||||
if (!mLinearVelocity) {
|
||||
aRv.NoteJSContextException(aCx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (mLinearVelocity) {
|
||||
JS::ExposeObjectToActiveJS(mLinearVelocity);
|
||||
}
|
||||
aRetval.set(mLinearVelocity);
|
||||
}
|
||||
|
||||
void
|
||||
VRPose::GetLinearAcceleration(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (!mLinearAcceleration && mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Position) {
|
||||
// Lazily create the Float32Array
|
||||
mLinearAcceleration = dom::Float32Array::Create(aCx, this, 3, mVRState.linearAcceleration);
|
||||
if (!mLinearAcceleration) {
|
||||
aRv.NoteJSContextException(aCx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (mLinearAcceleration) {
|
||||
JS::ExposeObjectToActiveJS(mLinearAcceleration);
|
||||
}
|
||||
aRetval.set(mLinearAcceleration);
|
||||
}
|
||||
|
||||
void
|
||||
VRPose::GetOrientation(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (!mOrientation && mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Orientation) {
|
||||
// Lazily create the Float32Array
|
||||
mOrientation = dom::Float32Array::Create(aCx, this, 4, mVRState.orientation);
|
||||
if (!mOrientation) {
|
||||
aRv.NoteJSContextException(aCx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (mOrientation) {
|
||||
JS::ExposeObjectToActiveJS(mOrientation);
|
||||
}
|
||||
aRetval.set(mOrientation);
|
||||
}
|
||||
|
||||
void
|
||||
VRPose::GetAngularVelocity(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (!mAngularVelocity && mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Orientation) {
|
||||
// Lazily create the Float32Array
|
||||
mAngularVelocity = dom::Float32Array::Create(aCx, this, 3, mVRState.angularVelocity);
|
||||
if (!mAngularVelocity) {
|
||||
aRv.NoteJSContextException(aCx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (mAngularVelocity) {
|
||||
JS::ExposeObjectToActiveJS(mAngularVelocity);
|
||||
}
|
||||
aRetval.set(mAngularVelocity);
|
||||
}
|
||||
|
||||
void
|
||||
VRPose::GetAngularAcceleration(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (!mAngularAcceleration && mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Orientation) {
|
||||
// Lazily create the Float32Array
|
||||
mAngularAcceleration = dom::Float32Array::Create(aCx, this, 3, mVRState.angularAcceleration);
|
||||
if (!mAngularAcceleration) {
|
||||
aRv.NoteJSContextException(aCx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (mAngularAcceleration) {
|
||||
JS::ExposeObjectToActiveJS(mAngularAcceleration);
|
||||
}
|
||||
aRetval.set(mAngularAcceleration);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
VRPose::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return VRPoseBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
/* virtual */ JSObject*
|
||||
VRDisplay::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return VRDisplayBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
VRDisplay::VRDisplay(nsPIDOMWindowInner* aWindow, gfx::VRDisplayClient* aClient)
|
||||
: DOMEventTargetHelper(aWindow)
|
||||
, mClient(aClient)
|
||||
, mDepthNear(0.01f) // Default value from WebVR Spec
|
||||
, mDepthFar(10000.0f) // Default value from WebVR Spec
|
||||
{
|
||||
MOZ_COUNT_CTOR(VRDisplay);
|
||||
mDisplayId = aClient->GetDisplayInfo().GetDisplayID();
|
||||
mDisplayName = NS_ConvertASCIItoUTF16(aClient->GetDisplayInfo().GetDisplayName());
|
||||
mCapabilities = new VRDisplayCapabilities(aWindow, aClient->GetDisplayInfo().GetCapabilities());
|
||||
}
|
||||
|
||||
VRDisplay::~VRDisplay()
|
||||
{
|
||||
ExitPresentInternal();
|
||||
MOZ_COUNT_DTOR(VRDisplay);
|
||||
}
|
||||
|
||||
void
|
||||
VRDisplay::LastRelease()
|
||||
{
|
||||
// We don't want to wait for the CC to free up the presentation
|
||||
// for use in other documents, so we do this in LastRelease().
|
||||
ExitPresentInternal();
|
||||
}
|
||||
|
||||
already_AddRefed<VREyeParameters>
|
||||
VRDisplay::GetEyeParameters(VREye aEye)
|
||||
{
|
||||
gfx::VRDisplayInfo::Eye eye = aEye == VREye::Left ? gfx::VRDisplayInfo::Eye_Left : gfx::VRDisplayInfo::Eye_Right;
|
||||
RefPtr<VREyeParameters> params =
|
||||
new VREyeParameters(GetParentObject(),
|
||||
mClient->GetDisplayInfo().GetEyeTranslation(eye),
|
||||
mClient->GetDisplayInfo().GetEyeFOV(eye),
|
||||
mClient->GetDisplayInfo().SuggestedEyeResolution());
|
||||
return params.forget();
|
||||
}
|
||||
|
||||
VRDisplayCapabilities*
|
||||
VRDisplay::Capabilities()
|
||||
{
|
||||
return mCapabilities;
|
||||
}
|
||||
|
||||
VRStageParameters*
|
||||
VRDisplay::GetStageParameters()
|
||||
{
|
||||
// XXX When we implement room scale experiences for OpenVR, we should return
|
||||
// something here.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
already_AddRefed<VRPose>
|
||||
VRDisplay::GetPose()
|
||||
{
|
||||
gfx::VRHMDSensorState state = mClient->GetSensorState();
|
||||
RefPtr<VRPose> obj = new VRPose(GetParentObject(), state);
|
||||
|
||||
return obj.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<VRPose>
|
||||
VRDisplay::GetImmediatePose()
|
||||
{
|
||||
gfx::VRHMDSensorState state = mClient->GetImmediateSensorState();
|
||||
RefPtr<VRPose> obj = new VRPose(GetParentObject(), state);
|
||||
|
||||
return obj.forget();
|
||||
}
|
||||
|
||||
void
|
||||
VRDisplay::ResetPose()
|
||||
{
|
||||
mClient->ZeroSensor();
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
VRDisplay::RequestPresent(const nsTArray<VRLayer>& aLayers, ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
|
||||
if (!global) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<Promise> promise = Promise::Create(global, aRv);
|
||||
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
NS_ENSURE_TRUE(obs, nullptr);
|
||||
|
||||
if (IsPresenting()) {
|
||||
// Only one presentation allowed per VRDisplay
|
||||
// on a first-come-first-serve basis.
|
||||
promise->MaybeRejectWithUndefined();
|
||||
} else {
|
||||
mPresentation = mClient->BeginPresentation(aLayers);
|
||||
|
||||
nsresult rv = obs->AddObserver(this, "inner-window-destroyed", false);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
mPresentation = nullptr;
|
||||
promise->MaybeRejectWithUndefined();
|
||||
} else {
|
||||
promise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
}
|
||||
}
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
VRDisplay::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
const char16_t* aData)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (strcmp(aTopic, "inner-window-destroyed") == 0) {
|
||||
nsCOMPtr<nsISupportsPRUint64> wrapper = do_QueryInterface(aSubject);
|
||||
NS_ENSURE_TRUE(wrapper, NS_ERROR_FAILURE);
|
||||
|
||||
uint64_t innerID;
|
||||
nsresult rv = wrapper->GetData(&innerID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!GetOwner() || GetOwner()->WindowID() == innerID) {
|
||||
ExitPresentInternal();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// This should not happen.
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
VRDisplay::ExitPresent(ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
|
||||
if (!global) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
ExitPresentInternal();
|
||||
|
||||
RefPtr<Promise> promise = Promise::Create(global, aRv);
|
||||
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
|
||||
|
||||
promise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
void
|
||||
VRDisplay::ExitPresentInternal()
|
||||
{
|
||||
mPresentation = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
VRDisplay::GetLayers(nsTArray<VRLayer>& result)
|
||||
{
|
||||
if (mPresentation) {
|
||||
mPresentation->GetDOMLayers(result);
|
||||
} else {
|
||||
result = nsTArray<VRLayer>();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VRDisplay::SubmitFrame(const Optional<NonNull<VRPose>>& aPose)
|
||||
{
|
||||
if (mPresentation) {
|
||||
if (aPose.WasPassed()) {
|
||||
mPresentation->SubmitFrame(aPose.Value().FrameID());
|
||||
} else {
|
||||
mPresentation->SubmitFrame(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t
|
||||
VRDisplay::RequestAnimationFrame(FrameRequestCallback& aCallback,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
|
||||
|
||||
int32_t handle;
|
||||
aError = vm->ScheduleFrameRequestCallback(aCallback, &handle);
|
||||
return handle;
|
||||
}
|
||||
|
||||
void
|
||||
VRDisplay::CancelAnimationFrame(int32_t aHandle, ErrorResult& aError)
|
||||
{
|
||||
gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
|
||||
vm->CancelFrameRequestCallback(aHandle);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
VRDisplay::IsPresenting() const
|
||||
{
|
||||
return mClient->GetIsPresenting();
|
||||
}
|
||||
|
||||
bool
|
||||
VRDisplay::IsConnected() const
|
||||
{
|
||||
return mClient->GetIsConnected();
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(VRDisplay, DOMEventTargetHelper, mCapabilities)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(VRDisplay, DOMEventTargetHelper)
|
||||
NS_IMPL_RELEASE_INHERITED(VRDisplay, DOMEventTargetHelper)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(VRDisplay)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, DOMEventTargetHelper)
|
||||
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
302
dom/vr/VRDisplay.h
Normal file
302
dom/vr/VRDisplay.h
Normal file
@ -0,0 +1,302 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef mozilla_dom_VRDisplay_h_
|
||||
#define mozilla_dom_VRDisplay_h_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/TypedArray.h"
|
||||
#include "mozilla/dom/VRDisplayBinding.h"
|
||||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
#include "mozilla/dom/DOMPoint.h"
|
||||
#include "mozilla/dom/DOMRect.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
#include "gfxVR.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
class VRDisplayClient;
|
||||
class VRDisplayPresentation;
|
||||
struct VRFieldOfView;
|
||||
enum class VRDisplayCapabilityFlags : uint16_t;
|
||||
struct VRHMDSensorState;
|
||||
}
|
||||
namespace dom {
|
||||
class Navigator;
|
||||
|
||||
class VRFieldOfView final : public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
VRFieldOfView(nsISupports* aParent,
|
||||
double aUpDegrees, double aRightDegrees,
|
||||
double aDownDegrees, double aLeftDegrees);
|
||||
VRFieldOfView(nsISupports* aParent, const gfx::VRFieldOfView& aSrc);
|
||||
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRFieldOfView)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRFieldOfView)
|
||||
|
||||
double UpDegrees() const { return mUpDegrees; }
|
||||
double RightDegrees() const { return mRightDegrees; }
|
||||
double DownDegrees() const { return mDownDegrees; }
|
||||
double LeftDegrees() const { return mLeftDegrees; }
|
||||
|
||||
nsISupports* GetParentObject() const { return mParent; }
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
protected:
|
||||
virtual ~VRFieldOfView() {}
|
||||
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
|
||||
double mUpDegrees;
|
||||
double mRightDegrees;
|
||||
double mDownDegrees;
|
||||
double mLeftDegrees;
|
||||
};
|
||||
|
||||
class VRDisplayCapabilities final : public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
VRDisplayCapabilities(nsISupports* aParent, const gfx::VRDisplayCapabilityFlags& aFlags)
|
||||
: mParent(aParent)
|
||||
, mFlags(aFlags)
|
||||
{
|
||||
}
|
||||
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRDisplayCapabilities)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRDisplayCapabilities)
|
||||
|
||||
nsISupports* GetParentObject() const
|
||||
{
|
||||
return mParent;
|
||||
}
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
bool HasPosition() const;
|
||||
bool HasOrientation() const;
|
||||
bool HasExternalDisplay() const;
|
||||
bool CanPresent() const;
|
||||
uint32_t MaxLayers() const;
|
||||
|
||||
protected:
|
||||
~VRDisplayCapabilities() {}
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
gfx::VRDisplayCapabilityFlags mFlags;
|
||||
};
|
||||
|
||||
class VRPose final : public nsWrapperCache
|
||||
{
|
||||
|
||||
public:
|
||||
VRPose(nsISupports* aParent, const gfx::VRHMDSensorState& aState);
|
||||
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRPose)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRPose)
|
||||
|
||||
double Timestamp() const { return mTimeStamp; }
|
||||
uint32_t FrameID() const { return mFrameId; }
|
||||
|
||||
void GetPosition(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& aRv);
|
||||
void GetLinearVelocity(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& aRv);
|
||||
void GetLinearAcceleration(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& aRv);
|
||||
void GetOrientation(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& aRv);
|
||||
void GetAngularVelocity(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& aRv);
|
||||
void GetAngularAcceleration(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& aRv);
|
||||
|
||||
nsISupports* GetParentObject() const { return mParent; }
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
protected:
|
||||
~VRPose() {}
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
|
||||
double mTimeStamp;
|
||||
uint32_t mFrameId;
|
||||
gfx::VRHMDSensorState mVRState;
|
||||
|
||||
JS::Heap<JSObject*> mPosition;
|
||||
JS::Heap<JSObject*> mLinearVelocity;
|
||||
JS::Heap<JSObject*> mLinearAcceleration;
|
||||
JS::Heap<JSObject*> mOrientation;
|
||||
JS::Heap<JSObject*> mAngularVelocity;
|
||||
JS::Heap<JSObject*> mAngularAcceleration;
|
||||
|
||||
};
|
||||
|
||||
class VRStageParameters final : public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
VRStageParameters(nsISupports* aParent,
|
||||
const gfx::Matrix4x4& aSittingToStandingTransform,
|
||||
const gfx::Size& aSize)
|
||||
: mParent(aParent)
|
||||
, mSittingToStandingTransform(aSittingToStandingTransform)
|
||||
, mSittingToStandingTransformArray(nullptr)
|
||||
, mSize(aSize)
|
||||
{
|
||||
}
|
||||
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRStageParameters)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRStageParameters)
|
||||
|
||||
void GetSittingToStandingTransform(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& aRv);
|
||||
float SizeX() const { return mSize.width; }
|
||||
float SizeZ() const { return mSize.height; }
|
||||
|
||||
nsISupports* GetParentObject() const { return mParent; }
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
protected:
|
||||
~VRStageParameters() {}
|
||||
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
|
||||
gfx::Matrix4x4 mSittingToStandingTransform;
|
||||
JS::Heap<JSObject*> mSittingToStandingTransformArray;
|
||||
gfx::Size mSize;
|
||||
};
|
||||
|
||||
class VREyeParameters final : public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
VREyeParameters(nsISupports* aParent,
|
||||
const gfx::Point3D& aEyeTranslation,
|
||||
const gfx::VRFieldOfView& aFOV,
|
||||
const gfx::IntSize& aRenderSize);
|
||||
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VREyeParameters)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VREyeParameters)
|
||||
|
||||
void GetOffset(JSContext* aCx, JS::MutableHandle<JSObject*> aRetVal,
|
||||
ErrorResult& aRv);
|
||||
|
||||
VRFieldOfView* FieldOfView();
|
||||
|
||||
uint32_t RenderWidth() const { return mRenderSize.width; }
|
||||
uint32_t RenderHeight() const { return mRenderSize.height; }
|
||||
|
||||
nsISupports* GetParentObject() const { return mParent; }
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
protected:
|
||||
~VREyeParameters() {}
|
||||
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
|
||||
|
||||
gfx::Point3D mEyeTranslation;
|
||||
gfx::IntSize mRenderSize;
|
||||
JS::Heap<JSObject*> mOffset;
|
||||
RefPtr<VRFieldOfView> mFOV;
|
||||
};
|
||||
|
||||
class VRDisplay final : public DOMEventTargetHelper
|
||||
, public nsIObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIOBSERVER
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(VRDisplay, DOMEventTargetHelper)
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
bool IsPresenting() const;
|
||||
bool IsConnected() const;
|
||||
|
||||
VRDisplayCapabilities* Capabilities();
|
||||
VRStageParameters* GetStageParameters();
|
||||
|
||||
uint32_t DisplayId() const { return mDisplayId; }
|
||||
void GetDisplayName(nsAString& aDisplayName) const { aDisplayName = mDisplayName; }
|
||||
|
||||
static bool RefreshVRDisplays(dom::Navigator* aNavigator);
|
||||
static void UpdateVRDisplays(nsTArray<RefPtr<VRDisplay> >& aDisplays,
|
||||
nsPIDOMWindowInner* aWindow);
|
||||
|
||||
gfx::VRDisplayClient *GetClient() {
|
||||
return mClient;
|
||||
}
|
||||
|
||||
virtual already_AddRefed<VREyeParameters> GetEyeParameters(VREye aEye);
|
||||
|
||||
already_AddRefed<VRPose> GetPose();
|
||||
already_AddRefed<VRPose> GetImmediatePose();
|
||||
void ResetPose();
|
||||
|
||||
double DepthNear() {
|
||||
return mDepthNear;
|
||||
}
|
||||
|
||||
double DepthFar() {
|
||||
return mDepthFar;
|
||||
}
|
||||
|
||||
void SetDepthNear(double aDepthNear) {
|
||||
// XXX When we start sending depth buffers to VRLayer's we will want
|
||||
// to communicate this with the VRDisplayHost
|
||||
mDepthNear = aDepthNear;
|
||||
}
|
||||
|
||||
void SetDepthFar(double aDepthFar) {
|
||||
// XXX When we start sending depth buffers to VRLayer's we will want
|
||||
// to communicate this with the VRDisplayHost
|
||||
mDepthFar = aDepthFar;
|
||||
}
|
||||
|
||||
already_AddRefed<Promise> RequestPresent(const nsTArray<VRLayer>& aLayers, ErrorResult& aRv);
|
||||
already_AddRefed<Promise> ExitPresent(ErrorResult& aRv);
|
||||
void GetLayers(nsTArray<VRLayer>& result);
|
||||
void SubmitFrame(const Optional<NonNull<VRPose>>& aPose);
|
||||
|
||||
int32_t RequestAnimationFrame(mozilla::dom::FrameRequestCallback& aCallback,
|
||||
mozilla::ErrorResult& aError);
|
||||
void CancelAnimationFrame(int32_t aHandle, mozilla::ErrorResult& aError);
|
||||
|
||||
protected:
|
||||
VRDisplay(nsPIDOMWindowInner* aWindow, gfx::VRDisplayClient* aClient);
|
||||
virtual ~VRDisplay();
|
||||
virtual void LastRelease() override;
|
||||
|
||||
void ExitPresentInternal();
|
||||
|
||||
RefPtr<gfx::VRDisplayClient> mClient;
|
||||
|
||||
uint32_t mDisplayId;
|
||||
nsString mDisplayName;
|
||||
|
||||
RefPtr<VRDisplayCapabilities> mCapabilities;
|
||||
|
||||
double mDepthNear;
|
||||
double mDepthFar;
|
||||
|
||||
RefPtr<gfx::VRDisplayPresentation> mPresentation;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
72
dom/vr/VREventObserver.cpp
Normal file
72
dom/vr/VREventObserver.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "VREventObserver.h"
|
||||
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "VRManagerChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
using namespace gfx;
|
||||
|
||||
/**
|
||||
* This class is used by nsGlobalWindow to implement window.onvrdisplayconnected,
|
||||
* window.onvrdisplaydisconnected, and window.onvrdisplaypresentchange.
|
||||
*/
|
||||
VREventObserver::VREventObserver(nsGlobalWindow* aGlobalWindow)
|
||||
: mWindow(aGlobalWindow)
|
||||
{
|
||||
MOZ_ASSERT(aGlobalWindow && aGlobalWindow->IsInnerWindow());
|
||||
|
||||
VRManagerChild* vmc = VRManagerChild::Get();
|
||||
if (vmc) {
|
||||
vmc->AddListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
VREventObserver::~VREventObserver()
|
||||
{
|
||||
VRManagerChild* vmc = VRManagerChild::Get();
|
||||
if (vmc) {
|
||||
vmc->RemoveListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VREventObserver::NotifyVRDisplayConnect()
|
||||
{
|
||||
if (mWindow->AsInner()->IsCurrentInnerWindow()) {
|
||||
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
|
||||
mWindow->GetOuterWindow()->DispatchCustomEvent(
|
||||
NS_LITERAL_STRING("vrdisplayconnected"));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VREventObserver::NotifyVRDisplayDisconnect()
|
||||
{
|
||||
if (mWindow->AsInner()->IsCurrentInnerWindow()) {
|
||||
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
|
||||
mWindow->GetOuterWindow()->DispatchCustomEvent(
|
||||
NS_LITERAL_STRING("vrdisplaydisconnected"));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VREventObserver::NotifyVRDisplayPresentChange()
|
||||
{
|
||||
if (mWindow->AsInner()->IsCurrentInnerWindow()) {
|
||||
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
|
||||
mWindow->GetOuterWindow()->DispatchCustomEvent(
|
||||
NS_LITERAL_STRING("vrdisplaypresentchange"));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
33
dom/vr/VREventObserver.h
Normal file
33
dom/vr/VREventObserver.h
Normal file
@ -0,0 +1,33 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef mozilla_dom_VREventObserver_h
|
||||
#define mozilla_dom_VREventObserver_h
|
||||
|
||||
class nsGlobalWindow;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class VREventObserver final
|
||||
{
|
||||
public:
|
||||
~VREventObserver();
|
||||
explicit VREventObserver(nsGlobalWindow* aGlobalWindow);
|
||||
|
||||
void NotifyVRDisplayConnect();
|
||||
void NotifyVRDisplayDisconnect();
|
||||
void NotifyVRDisplayPresentChange();
|
||||
|
||||
private:
|
||||
// Weak pointer, instance is owned by mWindow.
|
||||
nsGlobalWindow* MOZ_NON_OWNING_REF mWindow;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_VREventObserver_h
|
@ -5,11 +5,13 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
EXPORTS.mozilla.dom += [
|
||||
'VRDevice.h',
|
||||
'VRDisplay.h',
|
||||
'VREventObserver.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES = [
|
||||
'VRDevice.cpp',
|
||||
'VRDisplay.cpp',
|
||||
'VREventObserver.cpp',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
@ -247,23 +247,12 @@ Element implements ParentNode;
|
||||
Element implements Animatable;
|
||||
Element implements GeometryUtils;
|
||||
|
||||
// non-standard: allows passing options to Element.requestFullscreen
|
||||
dictionary RequestFullscreenOptions {
|
||||
// Which HMDVRDevice to go full screen on; also enables VR rendering.
|
||||
// If null, normal fullscreen is entered.
|
||||
HMDVRDevice? vrDisplay = null;
|
||||
};
|
||||
|
||||
// https://fullscreen.spec.whatwg.org/#api
|
||||
partial interface Element {
|
||||
/**
|
||||
* The options parameter is non-standard. In Gecko, it can be:
|
||||
* a RequestFullscreenOptions object
|
||||
*/
|
||||
[Throws, UnsafeInPrerendering, Func="nsDocument::IsUnprefixedFullscreenEnabled"]
|
||||
void requestFullscreen(optional any options);
|
||||
void requestFullscreen();
|
||||
[Throws, UnsafeInPrerendering, BinaryName="requestFullscreen"]
|
||||
void mozRequestFullScreen(optional any options);
|
||||
void mozRequestFullScreen();
|
||||
};
|
||||
|
||||
// https://w3c.github.io/pointerlock/#extensions-to-the-element-interface
|
||||
|
@ -341,7 +341,7 @@ partial interface Navigator {
|
||||
|
||||
partial interface Navigator {
|
||||
[Throws, Pref="dom.vr.enabled"]
|
||||
Promise<sequence<VRDevice>> getVRDevices();
|
||||
Promise<sequence<VRDisplay>> getVRDisplays();
|
||||
};
|
||||
|
||||
#ifdef MOZ_B2G_BT
|
||||
|
@ -1,130 +0,0 @@
|
||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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/. */
|
||||
|
||||
enum VREye {
|
||||
"left",
|
||||
"right"
|
||||
};
|
||||
|
||||
[Pref="dom.vr.enabled",
|
||||
HeaderFile="mozilla/dom/VRDevice.h"]
|
||||
interface VRFieldOfViewReadOnly {
|
||||
readonly attribute double upDegrees;
|
||||
readonly attribute double rightDegrees;
|
||||
readonly attribute double downDegrees;
|
||||
readonly attribute double leftDegrees;
|
||||
};
|
||||
|
||||
[Pref="dom.vr.enabled",
|
||||
HeaderFile="mozilla/dom/VRDevice.h",
|
||||
Constructor(optional VRFieldOfViewInit fov),
|
||||
Constructor(double upDegrees, double rightDegrees, double downDegrees, double leftDegrees)]
|
||||
interface VRFieldOfView : VRFieldOfViewReadOnly {
|
||||
inherit attribute double upDegrees;
|
||||
inherit attribute double rightDegrees;
|
||||
inherit attribute double downDegrees;
|
||||
inherit attribute double leftDegrees;
|
||||
};
|
||||
|
||||
dictionary VRFieldOfViewInit {
|
||||
double upDegrees = 0.0;
|
||||
double rightDegrees = 0.0;
|
||||
double downDegrees = 0.0;
|
||||
double leftDegrees = 0.0;
|
||||
};
|
||||
|
||||
[Pref="dom.vr.enabled",
|
||||
HeaderFile="mozilla/dom/VRDevice.h"]
|
||||
interface VRPositionState {
|
||||
readonly attribute double timeStamp;
|
||||
|
||||
readonly attribute boolean hasPosition;
|
||||
readonly attribute DOMPoint? position;
|
||||
readonly attribute DOMPoint? linearVelocity;
|
||||
readonly attribute DOMPoint? linearAcceleration;
|
||||
|
||||
readonly attribute boolean hasOrientation;
|
||||
// XXX should be DOMQuaternion as soon as we add that
|
||||
readonly attribute DOMPoint? orientation;
|
||||
readonly attribute DOMPoint? angularVelocity;
|
||||
readonly attribute DOMPoint? angularAcceleration;
|
||||
};
|
||||
|
||||
[Pref="dom.vr.enabled",
|
||||
HeaderFile="mozilla/dom/VRDevice.h"]
|
||||
interface VREyeParameters {
|
||||
/* These values are expected to be static per-device/per-user */
|
||||
[Constant, Cached] readonly attribute VRFieldOfView minimumFieldOfView;
|
||||
[Constant, Cached] readonly attribute VRFieldOfView maximumFieldOfView;
|
||||
[Constant, Cached] readonly attribute VRFieldOfView recommendedFieldOfView;
|
||||
[Constant, Cached] readonly attribute DOMPoint eyeTranslation;
|
||||
|
||||
/* These values will vary after a FOV has been set */
|
||||
[Constant, Cached] readonly attribute VRFieldOfView currentFieldOfView;
|
||||
[Constant, Cached] readonly attribute DOMRect renderRect;
|
||||
};
|
||||
|
||||
[Pref="dom.vr.enabled"]
|
||||
interface VRDevice {
|
||||
/**
|
||||
* An identifier for the distinct hardware unit that this
|
||||
* VR Device is a part of. All VRDevice/Sensors that come
|
||||
* from the same hardware will have the same hardwareId
|
||||
*/
|
||||
[Constant] readonly attribute DOMString hardwareUnitId;
|
||||
|
||||
/**
|
||||
* An identifier for this distinct sensor/device on a physical
|
||||
* hardware device. This shouldn't change across browser
|
||||
* restrats, allowing configuration data to be saved based on it.
|
||||
*/
|
||||
[Constant] readonly attribute DOMString deviceId;
|
||||
|
||||
/**
|
||||
* a device name, a user-readable name identifying it
|
||||
*/
|
||||
[Constant] readonly attribute DOMString deviceName;
|
||||
};
|
||||
|
||||
[Pref="dom.vr.enabled",
|
||||
HeaderFile="mozilla/dom/VRDevice.h"]
|
||||
interface HMDVRDevice : VRDevice {
|
||||
// Return the current VREyeParameters for the given eye
|
||||
VREyeParameters getEyeParameters(VREye whichEye);
|
||||
|
||||
// Set a field of view. If either of the fields of view is null,
|
||||
// or if their values are all zeros, then the recommended field of view
|
||||
// for that eye will be used.
|
||||
void setFieldOfView(optional VRFieldOfViewInit leftFOV,
|
||||
optional VRFieldOfViewInit rightFOV,
|
||||
optional double zNear = 0.01,
|
||||
optional double zFar = 10000.0);
|
||||
};
|
||||
|
||||
[Pref="dom.vr.enabled" ,
|
||||
HeaderFile="mozilla/dom/VRDevice.h"]
|
||||
interface PositionSensorVRDevice : VRDevice {
|
||||
/*
|
||||
* Return a VRPositionState dictionary containing the state of this position sensor
|
||||
* for the current frame if within a requestAnimationFrame callback, or for the
|
||||
* previous frame if not.
|
||||
*
|
||||
* The VRPositionState will contain the position, orientation, and velocity
|
||||
* and acceleration of each of these properties. Use "hasPosition" and "hasOrientation"
|
||||
* to check if the associated members are valid; if these are false, those members
|
||||
* will be null.
|
||||
*/
|
||||
[NewObject] VRPositionState getState();
|
||||
|
||||
/*
|
||||
* Return the current instantaneous sensor state.
|
||||
*/
|
||||
[NewObject] VRPositionState getImmediateState();
|
||||
|
||||
/* Reset this sensor, treating its current position and orientation
|
||||
* as the "origin/zero" values.
|
||||
*/
|
||||
void resetSensor();
|
||||
};
|
273
dom/webidl/VRDisplay.webidl
Normal file
273
dom/webidl/VRDisplay.webidl
Normal file
@ -0,0 +1,273 @@
|
||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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/. */
|
||||
|
||||
enum VREye {
|
||||
"left",
|
||||
"right"
|
||||
};
|
||||
|
||||
[Pref="dom.vr.enabled",
|
||||
HeaderFile="mozilla/dom/VRDisplay.h"]
|
||||
interface VRFieldOfView {
|
||||
readonly attribute double upDegrees;
|
||||
readonly attribute double rightDegrees;
|
||||
readonly attribute double downDegrees;
|
||||
readonly attribute double leftDegrees;
|
||||
};
|
||||
|
||||
typedef (HTMLCanvasElement or OffscreenCanvas) VRSource;
|
||||
|
||||
dictionary VRLayer {
|
||||
/**
|
||||
* XXX - When WebVR in WebWorkers is implemented, HTMLCanvasElement below
|
||||
* should be replaced with VRSource.
|
||||
*/
|
||||
HTMLCanvasElement? source = null;
|
||||
|
||||
/**
|
||||
* The left and right viewports contain 4 values defining the viewport
|
||||
* rectangles within the canvas to present to the eye in UV space.
|
||||
* [0] left offset of the viewport (0.0 - 1.0)
|
||||
* [1] top offset of the viewport (0.0 - 1.0)
|
||||
* [2] width of the viewport (0.0 - 1.0)
|
||||
* [3] height of the viewport (0.0 - 1.0)
|
||||
*
|
||||
* When no values are passed, they will be processed as though the left
|
||||
* and right sides of the viewport were passed:
|
||||
*
|
||||
* leftBounds: [0.0, 0.0, 0.5, 1.0]
|
||||
* rightBounds: [0.5, 0.0, 0.5, 1.0]
|
||||
*/
|
||||
sequence<float> leftBounds = [];
|
||||
sequence<float> rightBounds = [];
|
||||
};
|
||||
|
||||
/**
|
||||
* Values describing the capabilities of a VRDisplay.
|
||||
* These are expected to be static per-device/per-user.
|
||||
*/
|
||||
[Pref="dom.vr.enabled",
|
||||
HeaderFile="mozilla/dom/VRDisplay.h"]
|
||||
interface VRDisplayCapabilities {
|
||||
/**
|
||||
* hasPosition is true if the VRDisplay is capable of tracking its position.
|
||||
*/
|
||||
readonly attribute boolean hasPosition;
|
||||
|
||||
/**
|
||||
* hasOrientation is true if the VRDisplay is capable of tracking its orientation.
|
||||
*/
|
||||
readonly attribute boolean hasOrientation;
|
||||
|
||||
/**
|
||||
* Whether the VRDisplay is separate from the device’s
|
||||
* primary display. If presenting VR content will obscure
|
||||
* other content on the device, this should be false. When
|
||||
* false, the application should not attempt to mirror VR content
|
||||
* or update non-VR UI because that content will not be visible.
|
||||
*/
|
||||
readonly attribute boolean hasExternalDisplay;
|
||||
|
||||
/**
|
||||
* Whether the VRDisplay is capable of presenting content to an HMD or similar device.
|
||||
* Can be used to indicate “magic window” devices that are capable of 6DoF tracking but for
|
||||
* which requestPresent is not meaningful. If false then calls to requestPresent should
|
||||
* always fail, and getEyeParameters should return null.
|
||||
*/
|
||||
readonly attribute boolean canPresent;
|
||||
|
||||
/**
|
||||
* Indicates the maximum length of the array that requestPresent() will accept. MUST be 1 if
|
||||
canPresent is true, 0 otherwise.
|
||||
*/
|
||||
readonly attribute unsigned long maxLayers;
|
||||
};
|
||||
|
||||
/**
|
||||
* Values describing the the stage / play area for devices
|
||||
* that support room-scale experiences.
|
||||
*/
|
||||
[Pref="dom.vr.enabled",
|
||||
HeaderFile="mozilla/dom/VRDisplay.h"]
|
||||
interface VRStageParameters {
|
||||
/**
|
||||
* A 16-element array containing the components of a column-major 4x4
|
||||
* affine transform matrix. This matrix transforms the sitting-space position
|
||||
* returned by get{Immediate}Pose() to a standing-space position.
|
||||
*/
|
||||
[Throws] readonly attribute Float32Array sittingToStandingTransform;
|
||||
|
||||
/**
|
||||
* Dimensions of the play-area bounds. The bounds are defined
|
||||
* as an axis-aligned rectangle on the floor.
|
||||
* The center of the rectangle is at (0,0,0) in standing-space
|
||||
* coordinates.
|
||||
* These bounds are defined for safety purposes.
|
||||
* Content should not require the user to move beyond these
|
||||
* bounds; however, it is possible for the user to ignore
|
||||
* the bounds resulting in position values outside of
|
||||
* this rectangle.
|
||||
*/
|
||||
readonly attribute float sizeX;
|
||||
readonly attribute float sizeZ;
|
||||
};
|
||||
|
||||
[Pref="dom.vr.enabled",
|
||||
HeaderFile="mozilla/dom/VRDisplay.h"]
|
||||
interface VRPose {
|
||||
readonly attribute DOMHighResTimeStamp timestamp;
|
||||
|
||||
/**
|
||||
* position, linearVelocity, and linearAcceleration are 3-component vectors.
|
||||
* position is relative to a sitting space. Transforming this point with
|
||||
* VRStageParameters.sittingToStandingTransform converts this to standing space.
|
||||
*/
|
||||
[Constant, Throws] readonly attribute Float32Array? position;
|
||||
[Constant, Throws] readonly attribute Float32Array? linearVelocity;
|
||||
[Constant, Throws] readonly attribute Float32Array? linearAcceleration;
|
||||
|
||||
/* orientation is a 4-entry array representing the components of a quaternion. */
|
||||
[Constant, Throws] readonly attribute Float32Array? orientation;
|
||||
/* angularVelocity and angularAcceleration are the components of 3-dimensional vectors. */
|
||||
[Constant, Throws] readonly attribute Float32Array? angularVelocity;
|
||||
[Constant, Throws] readonly attribute Float32Array? angularAcceleration;
|
||||
};
|
||||
|
||||
[Pref="dom.vr.enabled",
|
||||
HeaderFile="mozilla/dom/VRDisplay.h"]
|
||||
interface VREyeParameters {
|
||||
/**
|
||||
* offset is a 3-component vector representing an offset to
|
||||
* translate the eye. This value may vary from frame
|
||||
* to frame if the user adjusts their headset ipd.
|
||||
*/
|
||||
[Constant, Throws] readonly attribute Float32Array offset;
|
||||
|
||||
/* These values may vary as the user adjusts their headset ipd. */
|
||||
[Constant] readonly attribute VRFieldOfView fieldOfView;
|
||||
|
||||
/**
|
||||
* renderWidth and renderHeight specify the recommended render target
|
||||
* size of each eye viewport, in pixels. If multiple eyes are rendered
|
||||
* in a single render target, then the render target should be made large
|
||||
* enough to fit both viewports.
|
||||
*/
|
||||
[Constant] readonly attribute unsigned long renderWidth;
|
||||
[Constant] readonly attribute unsigned long renderHeight;
|
||||
};
|
||||
|
||||
[Pref="dom.vr.enabled",
|
||||
HeaderFile="mozilla/dom/VRDisplay.h"]
|
||||
interface VRDisplay : EventTarget {
|
||||
readonly attribute boolean isConnected;
|
||||
readonly attribute boolean isPresenting;
|
||||
|
||||
/**
|
||||
* Dictionary of capabilities describing the VRDisplay.
|
||||
*/
|
||||
[Constant] readonly attribute VRDisplayCapabilities capabilities;
|
||||
|
||||
/**
|
||||
* If this VRDisplay supports room-scale experiences, the optional
|
||||
* stage attribute contains details on the room-scale parameters.
|
||||
*/
|
||||
readonly attribute VRStageParameters? stageParameters;
|
||||
|
||||
/* Return the current VREyeParameters for the given eye. */
|
||||
VREyeParameters getEyeParameters(VREye whichEye);
|
||||
|
||||
/**
|
||||
* An identifier for this distinct VRDisplay. Used as an
|
||||
* association point in the Gamepad API.
|
||||
*/
|
||||
[Constant] readonly attribute unsigned long displayId;
|
||||
|
||||
/**
|
||||
* A display name, a user-readable name identifying it.
|
||||
*/
|
||||
[Constant] readonly attribute DOMString displayName;
|
||||
|
||||
/**
|
||||
* Return a VRPose containing the future predicted pose of the VRDisplay
|
||||
* when the current frame will be presented. Subsequent calls to getPose()
|
||||
* MUST return a VRPose with the same values until the next call to
|
||||
* submitFrame().
|
||||
*
|
||||
* The VRPose will contain the position, orientation, velocity,
|
||||
* and acceleration of each of these properties.
|
||||
*/
|
||||
[NewObject] VRPose getPose();
|
||||
|
||||
/**
|
||||
* Return the current instantaneous pose of the VRDisplay, with no
|
||||
* prediction applied. Every call to getImmediatePose() may
|
||||
* return a different value, even within a single frame.
|
||||
*/
|
||||
[NewObject] VRPose getImmediatePose();
|
||||
|
||||
/**
|
||||
* Reset the pose for this display, treating its current position and
|
||||
* orientation as the "origin/zero" values. VRPose.position,
|
||||
* VRPose.orientation, and VRStageParameters.sittingToStandingTransform may be
|
||||
* updated when calling resetPose(). This should be called in only
|
||||
* sitting-space experiences.
|
||||
*/
|
||||
void resetPose();
|
||||
|
||||
/**
|
||||
* z-depth defining the near plane of the eye view frustum
|
||||
* enables mapping of values in the render target depth
|
||||
* attachment to scene coordinates. Initially set to 0.01.
|
||||
*/
|
||||
attribute double depthNear;
|
||||
|
||||
/**
|
||||
* z-depth defining the far plane of the eye view frustum
|
||||
* enables mapping of values in the render target depth
|
||||
* attachment to scene coordinates. Initially set to 10000.0.
|
||||
*/
|
||||
attribute double depthFar;
|
||||
|
||||
/**
|
||||
* The callback passed to `requestAnimationFrame` will be called
|
||||
* any time a new frame should be rendered. When the VRDisplay is
|
||||
* presenting the callback will be called at the native refresh
|
||||
* rate of the HMD. When not presenting this function acts
|
||||
* identically to how window.requestAnimationFrame acts. Content should
|
||||
* make no assumptions of frame rate or vsync behavior as the HMD runs
|
||||
* asynchronously from other displays and at differing refresh rates.
|
||||
*/
|
||||
[Throws] long requestAnimationFrame(FrameRequestCallback callback);
|
||||
|
||||
/**
|
||||
* Passing the value returned by `requestAnimationFrame` to
|
||||
* `cancelAnimationFrame` will unregister the callback.
|
||||
*/
|
||||
[Throws] void cancelAnimationFrame(long handle);
|
||||
|
||||
/**
|
||||
* Begin presenting to the VRDisplay. Must be called in response to a user gesture.
|
||||
* Repeat calls while already presenting will update the VRLayers being displayed.
|
||||
*/
|
||||
[Throws] Promise<void> requestPresent(sequence<VRLayer> layers);
|
||||
|
||||
/**
|
||||
* Stops presenting to the VRDisplay.
|
||||
*/
|
||||
[Throws] Promise<void> exitPresent();
|
||||
|
||||
/**
|
||||
* Get the layers currently being presented.
|
||||
*/
|
||||
sequence<VRLayer> getLayers();
|
||||
|
||||
/**
|
||||
* The VRLayer provided to the VRDisplay will be captured and presented
|
||||
* in the HMD. Calling this function has the same effect on the source
|
||||
* canvas as any other operation that uses its source image, and canvases
|
||||
* created without preserveDrawingBuffer set to true will be cleared.
|
||||
*/
|
||||
void submitFrame(optional VRPose pose);
|
||||
};
|
@ -503,6 +503,15 @@ interface ChromeWindow {
|
||||
void beginWindowMove(Event mouseDownEvent, optional Element? panel = null);
|
||||
};
|
||||
|
||||
partial interface Window {
|
||||
[Pref="dom.vr.enabled"]
|
||||
attribute EventHandler onvrdisplayconnect;
|
||||
[Pref="dom.vr.enabled"]
|
||||
attribute EventHandler onvrdisplaydisconnect;
|
||||
[Pref="dom.vr.enabled"]
|
||||
attribute EventHandler onvrdisplaypresentchange;
|
||||
};
|
||||
|
||||
Window implements ChromeWindow;
|
||||
Window implements GlobalFetch;
|
||||
Window implements ImageBitmapFactories;
|
||||
|
@ -581,7 +581,7 @@ WEBIDL_FILES = [
|
||||
'VideoStreamTrack.webidl',
|
||||
'VideoTrack.webidl',
|
||||
'VideoTrackList.webidl',
|
||||
'VRDevice.webidl',
|
||||
'VRDisplay.webidl',
|
||||
'VTTCue.webidl',
|
||||
'VTTRegion.webidl',
|
||||
'WaveShaperNode.webidl',
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
#include "prinit.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Snprintf.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsPrintfCString.h"
|
||||
|
||||
@ -178,10 +178,10 @@ int32_t WifiHotspotUtils::do_wifi_hostapd_get_stations()
|
||||
}
|
||||
stations++;
|
||||
|
||||
snprintf_literal(cmd, "STA-NEXT %s", addr);
|
||||
SprintfLiteral(cmd, "STA-NEXT %s", addr);
|
||||
while (sendCommand(ctrl_conn, cmd, addr, &addrLen) == 0) {
|
||||
stations++;
|
||||
snprintf_literal(cmd, "STA-NEXT %s", addr);
|
||||
SprintfLiteral(cmd, "STA-NEXT %s", addr);
|
||||
}
|
||||
|
||||
return stations;
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include <errno.h>
|
||||
#include <cutils/properties.h>
|
||||
#include "prinit.h"
|
||||
#include "mozilla/Snprintf.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
#include "js/CharacterEncoding.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
@ -369,10 +369,10 @@ public:
|
||||
char command[COMMAND_SIZE];
|
||||
if (!strcmp(iface, "p2p0")) {
|
||||
// Commands for p2p0 interface don't need prefix
|
||||
snprintf_literal(command, "%s", cmd);
|
||||
SprintfLiteral(command, "%s", cmd);
|
||||
}
|
||||
else {
|
||||
snprintf_literal(command, "IFNAME=%s %s", iface, cmd);
|
||||
SprintfLiteral(command, "IFNAME=%s %s", iface, cmd);
|
||||
}
|
||||
USE_DLFUNC(wifi_command)
|
||||
return wifi_command(command, buf, len);
|
||||
|
@ -1562,7 +1562,7 @@ XMLHttpRequestMainThread::PopulateNetworkInterfaceId()
|
||||
/*
|
||||
* "Copy" from a stream.
|
||||
*/
|
||||
NS_METHOD
|
||||
nsresult
|
||||
XMLHttpRequestMainThread::StreamReaderFunc(nsIInputStream* in,
|
||||
void* closure,
|
||||
const char* fromRawSegment,
|
||||
|
@ -511,12 +511,12 @@ protected:
|
||||
|
||||
nsresult DetectCharset();
|
||||
nsresult AppendToResponseText(const char * aBuffer, uint32_t aBufferLen);
|
||||
static NS_METHOD StreamReaderFunc(nsIInputStream* in,
|
||||
void* closure,
|
||||
const char* fromRawSegment,
|
||||
uint32_t toOffset,
|
||||
uint32_t count,
|
||||
uint32_t *writeCount);
|
||||
static nsresult StreamReaderFunc(nsIInputStream* in,
|
||||
void* closure,
|
||||
const char* fromRawSegment,
|
||||
uint32_t toOffset,
|
||||
uint32_t count,
|
||||
uint32_t *writeCount);
|
||||
nsresult CreateResponseParsedJSON(JSContext* aCx);
|
||||
void CreatePartialBlob(ErrorResult& aRv);
|
||||
bool CreateDOMBlob(nsIRequest *request);
|
||||
|
@ -37,7 +37,7 @@
|
||||
#include "prmem.h"
|
||||
#include "prnetdb.h"
|
||||
#include "mozilla/Likely.h"
|
||||
#include "mozilla/Snprintf.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
@ -514,9 +514,12 @@ gl::Error Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &so
|
||||
D3DSURFACE_DESC sourceDesc;
|
||||
surface->GetDesc(&sourceDesc);
|
||||
|
||||
const auto destWidth = sourceRect.right - sourceRect.left;
|
||||
const auto destHeight = sourceRect.bottom - sourceRect.top;
|
||||
|
||||
// Copy the render target into a texture
|
||||
IDirect3DTexture9 *texture;
|
||||
HRESULT result = device->CreateTexture(sourceRect.right - sourceRect.left, sourceRect.bottom - sourceRect.top, 1, D3DUSAGE_RENDERTARGET, sourceDesc.Format, D3DPOOL_DEFAULT, &texture, NULL);
|
||||
HRESULT result = device->CreateTexture(destWidth, destHeight, 1, D3DUSAGE_RENDERTARGET, sourceDesc.Format, D3DPOOL_DEFAULT, &texture, NULL);
|
||||
|
||||
if (FAILED(result))
|
||||
{
|
||||
@ -535,8 +538,40 @@ gl::Error Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &so
|
||||
}
|
||||
|
||||
mRenderer->endScene();
|
||||
result = device->StretchRect(surface, &sourceRect, textureSurface, NULL, D3DTEXF_NONE);
|
||||
|
||||
if (sourceRect.left < sourceDesc.Width && sourceRect.right > 0 &&
|
||||
sourceRect.top < sourceDesc.Height && sourceRect.bottom > 0)
|
||||
{
|
||||
RECT validSourceRect = sourceRect;
|
||||
RECT validDestRect = {0, 0, destWidth, destHeight};
|
||||
|
||||
if (sourceRect.left < 0) {
|
||||
validSourceRect.left += 0 - sourceRect.left;
|
||||
validDestRect.left += 0 - sourceRect.left;
|
||||
}
|
||||
|
||||
if (sourceRect.right > sourceDesc.Width) {
|
||||
validSourceRect.right -= sourceRect.right - sourceDesc.Width;
|
||||
validDestRect.right -= sourceRect.right - sourceDesc.Width;
|
||||
}
|
||||
|
||||
if (sourceRect.top < 0) {
|
||||
validSourceRect.top += 0 - sourceRect.top;
|
||||
validDestRect.top += 0 - sourceRect.top;
|
||||
}
|
||||
|
||||
if (sourceRect.bottom > sourceDesc.Height) {
|
||||
validSourceRect.bottom -= sourceRect.bottom - sourceDesc.Height;
|
||||
validDestRect.bottom -= sourceRect.bottom - sourceDesc.Height;
|
||||
}
|
||||
|
||||
ASSERT(validSourceRect.left < validSourceRect.right);
|
||||
ASSERT(validSourceRect.top < validSourceRect.bottom);
|
||||
ASSERT(validDestRect.left < validDestRect.right);
|
||||
ASSERT(validDestRect.top < validDestRect.bottom);
|
||||
result = device->StretchRect(surface, &validSourceRect, textureSurface,
|
||||
&validDestRect, D3DTEXF_NONE);
|
||||
}
|
||||
SafeRelease(textureSurface);
|
||||
|
||||
if (FAILED(result))
|
||||
|
@ -14,7 +14,7 @@ namespace gfx {
|
||||
|
||||
#define GFX_FALLBACK_MAP(_) \
|
||||
/* Name */ \
|
||||
_(USE_D3D11_WARP_COMPOSITOR) \
|
||||
_(PLACEHOLDER_DO_NOT_USE) \
|
||||
/* Add new entries above this comment */
|
||||
|
||||
enum class Fallback : uint32_t {
|
||||
|
@ -43,6 +43,7 @@ GPUParent::Init(base::ProcessId aParentPid,
|
||||
|
||||
// Ensure gfxPrefs are initialized.
|
||||
gfxPrefs::GetSingleton();
|
||||
gfxConfig::Init();
|
||||
gfxVars::Initialize();
|
||||
CompositorThreadHolder::Start();
|
||||
VRManager::ManagerInit();
|
||||
@ -162,6 +163,9 @@ GPUParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
mVsyncBridge->Shutdown();
|
||||
}
|
||||
CompositorThreadHolder::Shutdown();
|
||||
gfxVars::Shutdown();
|
||||
gfxConfig::Shutdown();
|
||||
gfxPrefs::DestroySingleton();
|
||||
XRE_ShutdownChildProcess();
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,10 @@
|
||||
#include "mozilla/ipc/ProcessChild.h"
|
||||
#include "GPUParent.h"
|
||||
|
||||
#if defined(XP_WIN)
|
||||
# include "mozilla/mscom/MainThreadRuntime.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
@ -25,7 +29,13 @@ public:
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(GPUProcessImpl);
|
||||
|
||||
GPUParent mGPU;
|
||||
|
||||
#if defined(XP_WIN)
|
||||
// This object initializes and configures COM.
|
||||
mozilla::mscom::MainThreadRuntime mCOMRuntime;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
|
@ -1,41 +1,40 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=8 et :
|
||||
*/
|
||||
/* 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/. */
|
||||
|
||||
using struct DxgiAdapterDesc from "mozilla/D3DMessageUtils.h";
|
||||
using mozilla::gfx::BackendType from "mozilla/gfx/Types.h";
|
||||
using mozilla::gfx::IntSize from "mozilla/gfx/Point.h";
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=8 et :
|
||||
*/
|
||||
/* 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/. */
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
struct DeviceInitData
|
||||
{
|
||||
bool useHwCompositing;
|
||||
|
||||
// Windows only.
|
||||
bool useD3D11;
|
||||
bool useD3D11WARP;
|
||||
bool d3d11TextureSharingWorks;
|
||||
bool useD2D1;
|
||||
DxgiAdapterDesc adapter;
|
||||
};
|
||||
|
||||
union GfxVarValue
|
||||
{
|
||||
using struct DxgiAdapterDesc from "mozilla/D3DMessageUtils.h";
|
||||
using mozilla::gfx::BackendType from "mozilla/gfx/Types.h";
|
||||
using mozilla::gfx::IntSize from "mozilla/gfx/Point.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
struct DeviceInitData
|
||||
{
|
||||
bool useHwCompositing;
|
||||
|
||||
// Windows only.
|
||||
bool useD3D11;
|
||||
bool d3d11TextureSharingWorks;
|
||||
bool useD2D1;
|
||||
DxgiAdapterDesc adapter;
|
||||
};
|
||||
|
||||
union GfxVarValue
|
||||
{
|
||||
BackendType;
|
||||
bool;
|
||||
IntSize;
|
||||
};
|
||||
|
||||
struct GfxVarUpdate
|
||||
{
|
||||
size_t index;
|
||||
GfxVarValue value;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
IntSize;
|
||||
};
|
||||
|
||||
struct GfxVarUpdate
|
||||
{
|
||||
size_t index;
|
||||
GfxVarValue value;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
@ -136,7 +136,6 @@ enum class EffectTypes : uint8_t {
|
||||
COMPONENT_ALPHA,
|
||||
SOLID_COLOR,
|
||||
RENDER_TARGET,
|
||||
VR_DISTORTION,
|
||||
MAX //sentinel for the count of all effect types
|
||||
};
|
||||
|
||||
|
@ -65,10 +65,3 @@ EffectColorMatrix::PrintInfo(std::stringstream& aStream, const char* aPrefix)
|
||||
AppendToString(aStream, mColorMatrix, " [matrix=", "]");
|
||||
}
|
||||
|
||||
void
|
||||
EffectVRDistortion::PrintInfo(std::stringstream& aStream, const char* aPrefix)
|
||||
{
|
||||
aStream << aPrefix;
|
||||
aStream << nsPrintfCString("EffectVRDistortion (0x%p) [hmd=%p] [render-target=%p] [texture=%p]",
|
||||
this, mHMD.get(), mRenderTarget.get(), mTexture).get();
|
||||
}
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "mozilla/mozalloc.h" // for operator delete, etc
|
||||
#include "nscore.h" // for nsACString
|
||||
#include "mozilla/EnumeratedArray.h"
|
||||
#include "gfxVR.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
@ -96,36 +95,6 @@ struct EffectMask : public Effect
|
||||
gfx::Matrix4x4 mMaskTransform;
|
||||
};
|
||||
|
||||
struct EffectVRDistortion : public Effect
|
||||
{
|
||||
EffectVRDistortion(gfx::VRHMDInfo* aHMD,
|
||||
CompositingRenderTarget* aRenderTarget)
|
||||
: Effect(EffectTypes::VR_DISTORTION)
|
||||
, mHMD(aHMD)
|
||||
, mRenderTarget(aRenderTarget)
|
||||
, mTexture(aRenderTarget)
|
||||
{}
|
||||
|
||||
EffectVRDistortion(gfx::VRHMDInfo* aHMD,
|
||||
TextureSource* aTexture)
|
||||
: Effect(EffectTypes::VR_DISTORTION)
|
||||
, mHMD(aHMD)
|
||||
, mRenderTarget(nullptr)
|
||||
, mTexture(aTexture)
|
||||
{}
|
||||
|
||||
virtual const char* Name() { return "EffectVRDistortion"; }
|
||||
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
|
||||
|
||||
RefPtr<gfx::VRHMDInfo> mHMD;
|
||||
RefPtr<CompositingRenderTarget> mRenderTarget;
|
||||
TextureSource* mTexture;
|
||||
|
||||
// The viewport for each eye in the source and
|
||||
// destination textures.
|
||||
gfx::IntRect mViewports[2];
|
||||
};
|
||||
|
||||
struct EffectBlendMode : public Effect
|
||||
{
|
||||
explicit EffectBlendMode(gfx::CompositionOp aBlendMode)
|
||||
|
@ -1123,9 +1123,7 @@ ContainerLayer::ContainerLayer(LayerManager* aManager, void* aImplData)
|
||||
mSupportsComponentAlphaChildren(false),
|
||||
mMayHaveReadbackChild(false),
|
||||
mChildrenChanged(false),
|
||||
mEventRegionsOverride(EventRegionsOverride::NoOverride),
|
||||
mVRDeviceID(0),
|
||||
mInputFrameID(0)
|
||||
mEventRegionsOverride(EventRegionsOverride::NoOverride)
|
||||
{
|
||||
MOZ_COUNT_CTOR(ContainerLayer);
|
||||
mContentFlags = 0; // Clear NO_TEXT, NO_TEXT_OVER_TRANSPARENT
|
||||
@ -1286,9 +1284,7 @@ ContainerLayer::FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
|
||||
aAttrs = ContainerLayerAttributes(mPreXScale, mPreYScale,
|
||||
mInheritedXScale, mInheritedYScale,
|
||||
mPresShellResolution, mScaleToResolution,
|
||||
mEventRegionsOverride,
|
||||
mVRDeviceID,
|
||||
mInputFrameID);
|
||||
mEventRegionsOverride);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -2190,9 +2186,6 @@ ContainerLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
|
||||
if (mEventRegionsOverride & EventRegionsOverride::ForceEmptyHitRegion) {
|
||||
aStream << " [force-ehr]";
|
||||
}
|
||||
if (mVRDeviceID) {
|
||||
aStream << nsPrintfCString(" [hmd=%lu] [hmdframe=%l]", mVRDeviceID, mInputFrameID).get();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -47,7 +47,6 @@
|
||||
#include "nscore.h" // for nsACString, nsAString
|
||||
#include "mozilla/Logging.h" // for PRLogModuleInfo
|
||||
#include "nsIWidget.h" // For plugin window configuration information structs
|
||||
#include "gfxVR.h"
|
||||
#include "ImageContainer.h"
|
||||
|
||||
class gfxContext;
|
||||
@ -1799,20 +1798,6 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the current effective transform with the given one,
|
||||
* returning the old one. This is currently added as a hack for VR
|
||||
* rendering, and might go away if we find a better way to do this.
|
||||
* If you think you have a need for this method, talk with
|
||||
* vlad/mstange/mwoodrow first.
|
||||
*/
|
||||
virtual gfx::Matrix4x4 ReplaceEffectiveTransform(const gfx::Matrix4x4& aNewEffectiveTransform) {
|
||||
gfx::Matrix4x4 old = mEffectiveTransform;
|
||||
mEffectiveTransform = aNewEffectiveTransform;
|
||||
ComputeEffectiveTransformForMaskLayers(mEffectiveTransform);
|
||||
return old;
|
||||
}
|
||||
|
||||
protected:
|
||||
Layer(LayerManager* aManager, void* aImplData);
|
||||
|
||||
@ -2213,39 +2198,6 @@ public:
|
||||
return mEventRegionsOverride;
|
||||
}
|
||||
|
||||
/**
|
||||
* VR
|
||||
*/
|
||||
void SetVRDeviceID(uint32_t aVRDeviceID) {
|
||||
mVRDeviceID = aVRDeviceID;
|
||||
Mutated();
|
||||
}
|
||||
uint32_t GetVRDeviceID() {
|
||||
return mVRDeviceID;
|
||||
}
|
||||
void SetInputFrameID(int32_t aInputFrameID) {
|
||||
mInputFrameID = aInputFrameID;
|
||||
Mutated();
|
||||
}
|
||||
int32_t GetInputFrameID() {
|
||||
return mInputFrameID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the current effective transform with the given one,
|
||||
* returning the old one. This is currently added as a hack for VR
|
||||
* rendering, and might go away if we find a better way to do this.
|
||||
* If you think you have a need for this method, talk with
|
||||
* vlad/mstange/mwoodrow first.
|
||||
*/
|
||||
gfx::Matrix4x4 ReplaceEffectiveTransform(const gfx::Matrix4x4& aNewEffectiveTransform) override {
|
||||
gfx::Matrix4x4 old = mEffectiveTransform;
|
||||
mEffectiveTransform = aNewEffectiveTransform;
|
||||
ComputeEffectiveTransformsForChildren(mEffectiveTransform);
|
||||
ComputeEffectiveTransformForMaskLayers(mEffectiveTransform);
|
||||
return old;
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class ReadbackProcessor;
|
||||
|
||||
@ -2305,8 +2257,6 @@ protected:
|
||||
// the intermediate surface.
|
||||
bool mChildrenChanged;
|
||||
EventRegionsOverride mEventRegionsOverride;
|
||||
uint32_t mVRDeviceID;
|
||||
int32_t mInputFrameID;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include "nsDebug.h" // for printf_stderr, NS_ASSERTION
|
||||
#include "nsXULAppAPI.h" // for XRE_GetProcessType, etc
|
||||
#include "TextureClientSharedSurface.h"
|
||||
#include "VRManagerChild.h"
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::gl;
|
||||
@ -86,7 +85,6 @@ CanvasClient2D::UpdateFromTexture(TextureClient* aTexture)
|
||||
t->mTextureClient = aTexture;
|
||||
t->mPictureRect = nsIntRect(nsIntPoint(0, 0), aTexture->GetSize());
|
||||
t->mFrameID = mFrameID;
|
||||
t->mInputFrameID = VRManagerChild::Get()->GetInputFrameID();
|
||||
|
||||
GetForwarder()->UseTextures(this, textures);
|
||||
aTexture->SyncWithObject(GetForwarder()->GetSyncObject());
|
||||
@ -156,7 +154,6 @@ CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
||||
t->mTextureClient = mBackBuffer;
|
||||
t->mPictureRect = nsIntRect(nsIntPoint(0, 0), mBackBuffer->GetSize());
|
||||
t->mFrameID = mFrameID;
|
||||
t->mInputFrameID = VRManagerChild::Get()->GetInputFrameID();
|
||||
GetForwarder()->UseTextures(this, textures);
|
||||
mBackBuffer->SyncWithObject(GetForwarder()->GetSyncObject());
|
||||
}
|
||||
@ -511,11 +508,6 @@ CanvasClientSharedSurface::Updated()
|
||||
t->mTextureClient = mFront;
|
||||
t->mPictureRect = nsIntRect(nsIntPoint(0, 0), mFront->GetSize());
|
||||
t->mFrameID = mFrameID;
|
||||
// XXX TODO - This reference to VRManagerChild will be moved with the
|
||||
// implementation of the WebVR 1.0 API, which will enable
|
||||
// the inputFrameID to be passed through Javascript with
|
||||
// the new VRDisplay API.
|
||||
t->mInputFrameID = VRManagerChild::Get()->GetInputFrameID();
|
||||
forwarder->UseTextures(this, textures);
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user