Merge mozilla-central to b2g-inbound on a CLOSED TREE

This commit is contained in:
Carsten "Tomcat" Book 2014-10-29 13:42:47 +01:00
Родитель 3033fd14c8 281b258180
Коммит 348b931e1c
178 изменённых файлов: 3392 добавлений и 1634 удалений

Просмотреть файл

@ -22,7 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Updating CLOBBER for Bug 1084342
There are some refactored files in in dom/bluetooth. Updating CLOBBER to not
leave artifacts from older builds.
Backing out bug 1087560 needs a CLOBBER

Просмотреть файл

@ -43,7 +43,7 @@ function runNext() {
ok(false, 'unexpected success, permission request should be denied');
runNext();
}, function failure(err) {
is(err.toLowerCase(), 'permission denied', 'expected permission denied');
is(err.name, 'PermissionDeniedError', 'expected permission denied');
runNext();
});
} else {

Просмотреть файл

@ -524,6 +524,20 @@ Sanitizer.prototype = {
let features = "chrome,all,dialog=no," + this.privateStateForNewWindow;
let newWindow = existingWindow.openDialog("chrome://browser/content/", "_blank",
features, defaultArgs);
#ifdef XP_MACOSX
function onFullScreen(e) {
newWindow.removeEventListener("fullscreen", onFullScreen);
let docEl = newWindow.document.documentElement;
let sizemode = docEl.getAttribute("sizemode");
if (!newWindow.fullScreen && sizemode == "fullscreen") {
docEl.setAttribute("sizemode", "normal");
e.preventDefault();
e.stopPropagation();
return false;
}
}
newWindow.addEventListener("fullscreen", onFullScreen);
#endif
// Window creation and destruction is asynchronous. We need to wait
// until all existing windows are fully closed, and the new window is
@ -537,6 +551,9 @@ Sanitizer.prototype = {
return;
Services.obs.removeObserver(onWindowOpened, "browser-delayed-startup-finished");
#ifdef XP_MACOSX
newWindow.removeEventListener("fullscreen", onFullScreen);
#endif
newWindowOpened = true;
// If we're the last thing to happen, invoke callback.
if (numWindowsClosing == 0)

Просмотреть файл

@ -223,6 +223,8 @@ function checkNotSharing() {
assertWebRTCIndicatorStatus(null);
}
const permissionError = "error: PermissionDeniedError: The user did not grant permission for the operation.";
let gTests = [
{
@ -381,7 +383,7 @@ let gTests = [
enableDevice("Camera", false);
enableDevice("Microphone", false);
yield promiseMessage("error: PERMISSION_DENIED", () => {
yield promiseMessage(permissionError, () => {
PopupNotifications.panel.firstChild.button.click();
});
@ -405,7 +407,7 @@ let gTests = [
expectObserverCalled("getUserMedia:request");
checkDeviceSelectors(true, true);
yield promiseMessage("error: PERMISSION_DENIED", () => {
yield promiseMessage(permissionError, () => {
activateSecondaryAction(kActionDeny);
});
@ -482,7 +484,7 @@ let gTests = [
enableDevice("Camera", aAllowVideo || aNever);
let expectedMessage =
(aAllowVideo || aAllowAudio) ? "ok" : "error: PERMISSION_DENIED";
(aAllowVideo || aAllowAudio) ? "ok" : permissionError;
yield promiseMessage(expectedMessage, () => {
activateSecondaryAction(aNever ? kActionNever : kActionAlways);
});
@ -587,14 +589,14 @@ let gTests = [
expectObserverCalled("getUserMedia:request");
// Deny the request to cleanup...
yield promiseMessage("error: PERMISSION_DENIED", () => {
yield promiseMessage(permissionError, () => {
activateSecondaryAction(kActionDeny);
});
expectObserverCalled("getUserMedia:response:deny");
expectObserverCalled("recording-window-ended");
}
else {
let expectedMessage = aExpectStream ? "ok" : "error: PERMISSION_DENIED";
let expectedMessage = aExpectStream ? "ok" : permissionError;
yield promiseMessage(expectedMessage, gum);
if (expectedMessage == "ok") {

Просмотреть файл

@ -1,5 +1,5 @@
[DEFAULT]
skip-if = buildapp == "mulet" || e10s
skip-if = buildapp == "mulet"
support-files =
head.js
support/test_967000_charEncoding_page.html
@ -34,6 +34,7 @@ skip-if = os == "mac"
skip-if = os == "linux"
[browser_901207_searchbar_in_panel.js]
skip-if = e10s # bug 1090656
[browser_913972_currentset_overflow.js]
skip-if = os == "linux"
@ -54,7 +55,6 @@ skip-if = os == "mac"
skip-if = os == "linux"
[browser_934951_zoom_in_toolbar.js]
skip-if = e10s # Bug ?????? - test uses promiseTabLoadEvent() which isn't e10s friendly.
[browser_938980_navbar_collapsed.js]
[browser_938995_indefaultstate_nonremovable.js]
[browser_940013_registerToolbarNode_calls_registerArea.js]
@ -83,7 +83,7 @@ skip-if = os == "linux" # Intermittent failures
[browser_947914_button_paste.js]
skip-if = os == "linux" # Intermittent failures
[browser_947914_button_print.js]
skip-if = os == "linux" # Intermittent failures
skip-if = os == "linux" || (os == "win" && e10s) # Intermittent failures on Linux, e10s issues on Windows (bug 1088714)
[browser_947914_button_savePage.js]
skip-if = os == "linux" # Intermittent failures
[browser_947914_button_zoomIn.js]
@ -100,11 +100,9 @@ skip-if = os == "linux" # Intermittent failures
[browser_962884_opt_in_disable_hyphens.js]
[browser_963639_customizing_attribute_non_customizable_toolbar.js]
[browser_967000_button_charEncoding.js]
skip-if = e10s # Bug ?????? - test uses promiseTabLoadEvent() which isn't e10s friendly.
skip-if = e10s # Bug 1088710
[browser_967000_button_feeds.js]
skip-if = buildapp == 'mulet' || e10s # Bug ?????? - test uses promiseTabLoadEvent() which isn't e10s friendly.
[browser_967000_button_sync.js]
skip-if = e10s # Bug ?????? - test uses promiseTabLoadEvent() which isn't e10s friendly.
[browser_967000_button_tabView.js]
[browser_968447_bookmarks_toolbar_items_in_panel.js]
skip-if = os == "linux" # Intemittent failures - bug 979207
@ -129,6 +127,7 @@ skip-if = os == "linux"
skip-if = os == "linux"
[browser_985815_propagate_setToolbarVisibility.js]
skip-if = e10s # bug 1090635
[browser_981305_separator_insertion.js]
[browser_988072_sidebar_events.js]
[browser_989338_saved_placements_not_resaved.js]
@ -138,6 +137,7 @@ skip-if = os == "linux"
[browser_987185_syncButton.js]
[browser_987492_window_api.js]
[browser_987640_charEncoding.js]
skip-if = e10s # Bug 1088710
[browser_992747_toggle_noncustomizable_toolbar.js]
[browser_993322_widget_notoolbar.js]
[browser_995164_registerArea_during_customize_mode.js]

Просмотреть файл

@ -26,6 +26,37 @@ loop.shared.mixins = (function() {
rootObject = obj;
}
/**
* window.location mixin. Handles changes in the call url.
* Forces a reload of the page to ensure proper state of the webapp
*
* @type {Object}
*/
var UrlHashChangeMixin = {
propTypes: {
onUrlHashChange: React.PropTypes.func.isRequired
},
componentDidMount: function() {
rootObject.addEventListener("hashchange", this.onUrlHashChange, false);
},
componentWillUnmount: function() {
rootObject.removeEventListener("hashchange", this.onUrlHashChange, false);
}
};
/**
* Document location mixin.
*
* @type {Object}
*/
var DocumentLocationMixin = {
locationReload: function() {
rootObject.location.reload();
}
};
/**
* Dropdown menu mixin.
* @type {Object}
@ -151,6 +182,8 @@ loop.shared.mixins = (function() {
AudioMixin: AudioMixin,
setRootObject: setRootObject,
DropdownMenuMixin: DropdownMenuMixin,
DocumentVisibilityMixin: DocumentVisibilityMixin
DocumentVisibilityMixin: DocumentVisibilityMixin,
DocumentLocationMixin: DocumentLocationMixin,
UrlHashChangeMixin: UrlHashChangeMixin
};
})();

Просмотреть файл

@ -859,6 +859,10 @@ loop.webapp = (function($, _, OT, mozL10n) {
* of the webapp page.
*/
var WebappRootView = React.createClass({displayName: 'WebappRootView',
mixins: [sharedMixins.UrlHashChangeMixin,
sharedMixins.DocumentLocationMixin],
propTypes: {
client: React.PropTypes.instanceOf(loop.StandaloneClient).isRequired,
conversation: React.PropTypes.oneOfType([
@ -879,6 +883,10 @@ loop.webapp = (function($, _, OT, mozL10n) {
};
},
onUrlHashChange: function() {
this.locationReload();
},
render: function() {
if (this.state.unsupportedDevice) {
return UnsupportedDeviceView(null);

Просмотреть файл

@ -859,6 +859,10 @@ loop.webapp = (function($, _, OT, mozL10n) {
* of the webapp page.
*/
var WebappRootView = React.createClass({
mixins: [sharedMixins.UrlHashChangeMixin,
sharedMixins.DocumentLocationMixin],
propTypes: {
client: React.PropTypes.instanceOf(loop.StandaloneClient).isRequired,
conversation: React.PropTypes.oneOfType([
@ -879,6 +883,10 @@ loop.webapp = (function($, _, OT, mozL10n) {
};
},
onUrlHashChange: function() {
this.locationReload();
},
render: function() {
if (this.state.unsupportedDevice) {
return <UnsupportedDeviceView />;

Просмотреть файл

@ -21,6 +21,75 @@ describe("loop.shared.mixins", function() {
sandbox.restore();
});
describe("loop.webapp.UrlHashChangeMixin", function() {
function createTestComponent(onUrlHashChange) {
var TestComp = React.createClass({
mixins: [loop.shared.mixins.UrlHashChangeMixin],
onUrlHashChange: onUrlHashChange || function(){},
render: function() {
return React.DOM.div();
}
});
return new TestComp();
}
it("should watch for hashchange event", function() {
var addEventListener = sandbox.spy();
sharedMixins.setRootObject({
addEventListener: addEventListener
});
TestUtils.renderIntoDocument(createTestComponent());
sinon.assert.calledOnce(addEventListener);
sinon.assert.calledWith(addEventListener, "hashchange");
});
it("should call onUrlHashChange when the url is updated", function() {
sharedMixins.setRootObject({
addEventListener: function(name, cb) {
if (name === "hashchange") {
cb();
}
}
});
var onUrlHashChange = sandbox.stub();
TestUtils.renderIntoDocument(createTestComponent(onUrlHashChange));
sinon.assert.calledOnce(onUrlHashChange);
});
});
describe("loop.webapp.DocumentLocationMixin", function() {
var reloadStub, TestComp;
beforeEach(function() {
reloadStub = sandbox.stub();
sharedMixins.setRootObject({
location: {
reload: reloadStub
}
});
TestComp = React.createClass({
mixins: [loop.shared.mixins.DocumentLocationMixin],
render: function() {
return React.DOM.div();
}
});
});
it("should call window.location.reload", function() {
var comp = TestUtils.renderIntoDocument(TestComp());
comp.locationReload();
sinon.assert.calledOnce(reloadStub);
});
});
describe("loop.panel.DocumentVisibilityMixin", function() {
var comp, TestComp, onDocumentVisibleStub, onDocumentHiddenStub;

Просмотреть файл

@ -514,7 +514,8 @@ describe("loop.webapp", function() {
notifications: notifications,
sdk: sdk,
conversation: conversationModel,
feedbackApiClient: feedbackApiClient
feedbackApiClient: feedbackApiClient,
onUrlHashChange: sandbox.stub()
}));
}

Просмотреть файл

@ -64,7 +64,7 @@ function handleRequest(aSubject, aTopic, aData) {
constraints, devices, secure);
},
function (error) {
// bug 827146 -- In the future, the UI should catch NO_DEVICES_FOUND
// bug 827146 -- In the future, the UI should catch NotFoundError
// and allow the user to plug in a device, instead of immediately failing.
denyRequest({callID: aSubject.callID}, error);
},
@ -108,7 +108,7 @@ function prompt(aContentWindow, aWindowID, aCallID, aConstraints, aDevices, aSec
requestTypes.push("Microphone");
if (!requestTypes.length) {
denyRequest({callID: aCallID}, "NO_DEVICES_FOUND");
denyRequest({callID: aCallID}, "NotFoundError");
return;
}

Просмотреть файл

@ -838,7 +838,17 @@ this.UITour = {
highlighter.parentElement.setAttribute("targetName", aTarget.targetName);
highlighter.parentElement.hidden = false;
let targetRect = aTarget.node.getBoundingClientRect();
let highlightAnchor;
// If the target is in the overflow panel, just highlight the overflow button.
if (aTarget.node.getAttribute("overflowedItem")) {
let doc = aTarget.node.ownerDocument;
let placement = CustomizableUI.getPlacementOfWidget(aTarget.widgetName || aTarget.node.id);
let areaNode = doc.getElementById(placement.area);
highlightAnchor = areaNode.overflowable._chevron;
} else {
highlightAnchor = aTarget.node;
}
let targetRect = highlightAnchor.getBoundingClientRect();
let highlightHeight = targetRect.height;
let highlightWidth = targetRect.width;
let minDimension = Math.min(highlightHeight, highlightWidth);
@ -874,7 +884,7 @@ this.UITour = {
let offsetY = paddingLeftPx
- (Math.max(0, highlightHeightWithMin - targetRect.height) / 2);
this._addAnnotationPanelMutationObserver(highlighter.parentElement);
highlighter.parentElement.openPopup(aTarget.node, "overlap", offsetX, offsetY);
highlighter.parentElement.openPopup(highlightAnchor, "overlap", offsetX, offsetY);
}
// Prevent showing a panel at an undefined position.

Просмотреть файл

@ -18,6 +18,23 @@
%define conditionalForwardWithUrlbar window:not([chromehidden~="toolbar"]) #urlbar-wrapper
%define conditionalForwardWithUrlbarWidth 30
:root {
--toolbarbutton-hover-background: hsla(0,0%,100%,.3) linear-gradient(hsla(0,0%,100%,.7), hsla(0,0%,100%,.2));
--toolbarbutton-hover-boxshadow: 0 1px 0 hsla(0,0%,100%,.3) inset, 0 0 0 1px hsla(0,0%,100%,.2) inset, 0 1px 0 hsla(0,0%,0%,.03);
--toolbarbutton-hover-bordercolor: rgb(154,154,154);
--toolbarbutton-active-boxshadow: 0 1px 1px hsla(0,0%,0%,.1) inset, 0 0 1px hsla(0,0%,0%,.3) inset;
--toolbarbutton-active-bordercolor: rgb(154,154,154);
--toolbarbutton-active-background: rgba(154,154,154,.5) linear-gradient(hsla(0,0%,100%,.7), hsla(0,0%,100%,.4));
--toolbarbutton-checkedhover-backgroundcolor: rgba(90%,90%,90%,.4);
--toolbarbutton-combined-boxshadow: 0 0 0 1px hsla(0,0%,100%,.2);
--toolbarbutton-combined-backgroundimage: linear-gradient(hsla(210,54%,20%,.2) 0, hsla(210,54%,20%,.2) 18px);
--verified-identity-box-backgroundcolor: #fff;
}
#menubar-items {
-moz-box-orient: vertical; /* for flex hack */
}
@ -590,12 +607,11 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
:-moz-any(#TabsToolbar, #nav-bar) .toolbarbutton-1:not([disabled=true]):not([open]):hover > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon,
:-moz-any(#TabsToolbar, #nav-bar) .toolbarbutton-1:not([disabled=true]):hover > .toolbarbutton-badge-container > .toolbarbutton-icon,
:-moz-any(#TabsToolbar, #nav-bar) .toolbarbutton-1:not([disabled=true]):hover > .toolbarbutton-icon {
background-color: hsla(0,0%,100%,.3);
background-image: linear-gradient(hsla(0,0%,100%,.7), hsla(0,0%,100%,.2));
border: 1px solid rgb(154,154,154);
box-shadow: 0 1px 0 hsla(0,0%,100%,.3) inset,
0 0 0 1px hsla(0,0%,100%,.2) inset,
0 1px 0 hsla(0,0%,0%,.03);
background: var(--toolbarbutton-hover-background);
border-width: 1px;
border-style: solid;
border-color: var(--toolbarbutton-hover-bordercolor);
box-shadow: var(--toolbarbutton-hover-boxshadow);
}
:-moz-any(#TabsToolbar, #nav-bar) .toolbarbutton-1:hover > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon,
@ -608,16 +624,16 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
:-moz-any(#TabsToolbar, #nav-bar) .toolbarbutton-1[open="true"] > .toolbarbutton-menubutton-dropmarker:not([disabled=true]) > .dropmarker-icon,
:-moz-any(#TabsToolbar, #nav-bar) .toolbarbutton-1:not([disabled=true]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-badge-container > .toolbarbutton-icon,
:-moz-any(#TabsToolbar, #nav-bar) .toolbarbutton-1:not([disabled=true]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-icon {
background-color: rgba(154,154,154,.5);
background-image: linear-gradient(hsla(0,0%,100%,.7), hsla(0,0%,100%,.4));
border: 1px solid rgb(154,154,154);
box-shadow: 0 1px 1px hsla(0,0%,0%,.1) inset,
0 0 1px hsla(0,0%,0%,.3) inset;
background: var(--toolbarbutton-active-background);
box-shadow: var(--toolbarbutton-active-boxshadow);
border-width: 1px;
border-style: solid;
border-color: var(--toolbarbutton-active-bordercolor);
transition-duration: 10ms;
}
:-moz-any(#TabsToolbar, #nav-bar) .toolbarbutton-1[checked]:not(:active):hover > .toolbarbutton-icon {
background-color: rgba(90%,90%,90%,.4);
background-color: var(--toolbarbutton-checkedhover-backgroundcolor);
transition: background-color 150ms;
}
@ -633,12 +649,12 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
width: 1px;
height: 18px;
-moz-margin-end: -1px;
background-image: linear-gradient(hsla(210,54%,20%,.2) 0, hsla(210,54%,20%,.2) 18px);
background-image: var(--toolbarbutton-combined-backgroundimage);
background-clip: padding-box;
background-position: center;
background-repeat: no-repeat;
background-size: 1px 18px;
box-shadow: 0 0 0 1px hsla(0,0%,100%,.2);
box-shadow: var(--toolbarbutton-combined-boxshadow);
}
:-moz-any(#TabsToolbar, #nav-bar) .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
@ -971,7 +987,7 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
}
#identity-box.verifiedIdentity:not(:-moz-lwtheme) {
background-color: #fff;
background-color: var(--verified-identity-box-backgroundcolor);
}
#identity-box:-moz-focusring {

Просмотреть файл

@ -17,6 +17,28 @@
%define conditionalForwardWithUrlbar window:not([chromehidden~="toolbar"]) #urlbar-wrapper
%define conditionalForwardWithUrlbarWidth 30
:root {
--toolbarbutton-hover-background: hsla(210,4%,10%,.08);
--toolbarbutton-hover-bordercolor: hsla(210,4%,10%,.1);
--toolbarbutton-hover-boxshadow: none;
--toolbarbutton-active-background: hsla(210,4%,10%,.12);
--toolbarbutton-active-bordercolor: hsla(210,4%,10%,.2) transparent transparent;
--toolbarbutton-active-boxshadow: 0 1px 0 0 hsla(210,4%,10%,.1) inset;
--toolbarbutton-checkedhover-backgroundcolor: hsla(210,4%,10%,.12);
--toolbarbutton-combined-boxshadow: none;
--toolbarbutton-combined-backgroundimage: linear-gradient(hsla(210,54%,20%,.2) 0, hsla(210,54%,20%,.2) 16px);
--verified-identity-box-backgroundcolor: #FFF;
--urlbar-dropmarker-url: url("chrome://browser/skin/urlbar-history-dropmarker.png");
--urlbar-dropmarker-region: rect(0px, 11px, 14px, 0px);
--urlbar-dropmarker-hover-region: rect(0px, 22px, 14px, 11px);
--urlbar-dropmarker-active-region: rect(0px, 33px, 14px, 22px);
}
#menubar-items {
-moz-box-orient: vertical; /* for flex hack */
}
@ -663,6 +685,27 @@ toolbar[brighttext] .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
(-moz-os-version: windows-win7) {
%endif
/* < Win8 */
:root {
--toolbarbutton-hover-background: linear-gradient(hsla(0,0%,100%,.6), hsla(0,0%,100%,.1));
--toolbarbutton-hover-bordercolor: hsla(210,54%,20%,.15) hsla(210,54%,20%,.2) hsla(210,54%,20%,.25);
--toolbarbutton-hover-boxshadow: 0 1px hsla(0,0%,100%,.3) inset,
0 1px hsla(210,54%,20%,.03),
0 0 2px hsla(210,54%,20%,.1);
--toolbarbutton-active-background: hsla(210,54%,20%,.15) linear-gradient(hsla(0,0%,100%,.6), hsla(0,0%,100%,.1));
--toolbarbutton-active-bordercolor: hsla(210,54%,20%,.3) hsla(210,54%,20%,.35) hsla(210,54%,20%,.4);
--toolbarbutton-active-boxshadow: 0 1px 1px hsla(210,54%,20%,.1) inset,
0 0 1px hsla(210,54%,20%,.2) inset,
/* allows keyhole-forward-clip-path to be used for non-hover as well as hover: */
0 1px 0 hsla(210,54%,20%,0),
0 0 2px hsla(210,54%,20%,0);
--toolbarbutton-checkedhover-backgroundcolor: rgba(90%,90%,90%,.4);
--toolbarbutton-combined-backgroundimage: linear-gradient(hsla(210,54%,20%,.2) 0, hsla(210,54%,20%,.2) 18px);
--toolbarbutton-combined-boxshadow: 0 0 0 1px hsla(0,0%,100%,.2);
}
#nav-bar .toolbarbutton-1 > .toolbarbutton-icon,
#nav-bar .toolbarbutton-1 > .toolbarbutton-text,
#nav-bar .toolbarbutton-1 > .toolbarbutton-badge-container,
@ -732,7 +775,8 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
width: 1px;
height: 16px;
-moz-margin-end: -1px;
background-image: linear-gradient(hsla(210,54%,20%,.2) 0, hsla(210,54%,20%,.2) 16px);
background-image: var(--toolbarbutton-combined-backgroundimage);
box-shadow: var(--toolbarbutton-combined-boxshadow);
background-clip: padding-box;
background-position: center;
background-repeat: no-repeat;
@ -751,8 +795,9 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
#nav-bar .toolbarbutton-1:not([disabled=true]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-badge-container,
@conditionalForwardWithUrlbar@ > #forward-button:not([open]):not(:active):not([disabled]):hover > .toolbarbutton-icon,
#nav-bar .toolbarbutton-1:not([buttonover]):not([open]):not(:active):hover > .toolbarbutton-menubutton-dropmarker:not([disabled]) > .dropmarker-icon {
background-color: hsla(210,4%,10%,.08);
border-color: hsla(210,4%,10%,.1);
background: var(--toolbarbutton-hover-background);
border-color: var(--toolbarbutton-hover-bordercolor);
box-shadow: var(--toolbarbutton-hover-boxshadow);
}
%ifdef WINDOWS_AERO
@ -762,17 +807,8 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
/* < Win8 */
#nav-bar .toolbarbutton-1:not(:hover):not(:active):not([open]) > .toolbarbutton-menubutton-dropmarker::before,
#nav-bar .toolbaritem-combined-buttons > .toolbarbutton-1:-moz-any(:not(:hover):not([open]),[disabled]) + .toolbarbutton-1:-moz-any(:not(:hover):not([open]),[disabled])::before {
content: "";
display: -moz-box;
width: 1px;
height: 18px;
-moz-margin-end: -1px;
background-image: linear-gradient(hsla(210,54%,20%,.2) 0, hsla(210,54%,20%,.2) 18px);
background-clip: padding-box;
background-position: center;
background-repeat: no-repeat;
background-size: 1px 18px;
box-shadow: 0 0 0 1px hsla(0,0%,100%,.2);
}
#nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-button > .toolbarbutton-icon:-moz-locale-dir(ltr),
@ -787,21 +823,6 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
border-bottom-left-radius: 0;
}
#nav-bar .toolbarbutton-1:not([disabled=true]) > .toolbarbutton-menubutton-button[open] + .toolbarbutton-menubutton-dropmarker > .dropmarker-icon,
#nav-bar .toolbarbutton-1:not([disabled]):-moz-any(:hover,[open]) > .toolbarbutton-menubutton-button > .toolbarbutton-icon,
#nav-bar .toolbarbutton-1:not([disabled]):hover > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon,
#nav-bar .toolbarbutton-1:not([disabled]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-icon,
#nav-bar .toolbarbutton-1:not([disabled]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-text,
#nav-bar .toolbarbutton-1:not([disabled]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-badge-container,
@conditionalForwardWithUrlbar@ > .toolbarbutton-1:-moz-any([disabled],:not([open]):not([disabled]):not(:active)) > .toolbarbutton-icon {
background-image: linear-gradient(hsla(0,0%,100%,.6), hsla(0,0%,100%,.1));
background-color: transparent;
border-color: hsla(210,54%,20%,.15) hsla(210,54%,20%,.2) hsla(210,54%,20%,.25);
box-shadow: 0 1px hsla(0,0%,100%,.3) inset,
0 1px hsla(210,54%,20%,.03),
0 0 2px hsla(210,54%,20%,.1);
}
#nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-button:not([disabled]):not([open]):not(:active):hover > .toolbarbutton-icon,
#nav-bar .toolbarbutton-1:not([buttonover]):not([open]):not(:active):hover > .toolbarbutton-menubutton-dropmarker:not([disabled]) > .dropmarker-icon,
@conditionalForwardWithUrlbar@ > #forward-button:not([open]):not(:active):not([disabled]):hover > .toolbarbutton-icon {
@ -819,9 +840,9 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
#nav-bar .toolbarbutton-1:not([disabled=true]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-icon,
#nav-bar .toolbarbutton-1:not([disabled=true]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-text,
#nav-bar .toolbarbutton-1:not([disabled=true]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-badge-container {
background-color: hsla(210,4%,10%,.12);
border-top-color: hsla(210,4%,10%,.2);
box-shadow: 0 1px 0 0 hsla(210,4%,10%,.1) inset;
background: var(--toolbarbutton-active-background);
border-color: var(--toolbarbutton-active-bordercolor);
box-shadow: var(--toolbarbutton-active-boxshadow);
transition-duration: 10ms;
}
@ -835,14 +856,6 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
#nav-bar .toolbarbutton-1:not([disabled]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-icon,
#nav-bar .toolbarbutton-1:not([disabled]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-text,
#nav-bar .toolbarbutton-1:not([disabled]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-badge-container {
background-image: linear-gradient(hsla(0,0%,100%,.6), hsla(0,0%,100%,.1));
background-color: hsla(210,54%,20%,.15);
border-color: hsla(210,54%,20%,.3) hsla(210,54%,20%,.35) hsla(210,54%,20%,.4);
box-shadow: 0 1px 1px hsla(210,54%,20%,.1) inset,
0 0 1px hsla(210,54%,20%,.2) inset,
/* allows keyhole-forward-clip-path to be used for non-hover as well as hover: */
0 1px 0 hsla(210,54%,20%,0),
0 0 2px hsla(210,54%,20%,0);
text-shadow: none;
transition: none;
}
@ -852,7 +865,7 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
}
#nav-bar .toolbarbutton-1[checked]:not(:active):hover > .toolbarbutton-icon {
background-color: rgba(90%,90%,90%,.4);
background-color: var(--toolbarbutton-checkedhover-backgroundcolor);
transition: background-color .4s;
}
%ifdef WINDOWS_AERO
@ -1317,7 +1330,7 @@ html|*.urlbar-input:-moz-lwtheme::-moz-placeholder,
}
#identity-box.verifiedIdentity:not(:-moz-lwtheme) {
background-color: #fff;
background-color: var(--verified-identity-box-backgroundcolor);
}
#identity-box:-moz-focusring {
@ -1338,19 +1351,19 @@ html|*.urlbar-input:-moz-lwtheme::-moz-placeholder,
background-color: transparent;
border: none;
width: auto;
list-style-image: url("chrome://browser/skin/urlbar-history-dropmarker.png");
-moz-image-region: rect(0px, 11px, 14px, 0px);
list-style-image: var(--urlbar-dropmarker-url);
-moz-image-region: var(--urlbar-dropmarker-region);
}
.urlbar-history-dropmarker:hover {
background-image: radial-gradient(circle closest-side, hsla(205,100%,70%,.3), transparent);
-moz-image-region: rect(0px, 22px, 14px, 11px);
-moz-image-region: var(--urlbar-dropmarker-hover-region);
}
.urlbar-history-dropmarker:hover:active,
.urlbar-history-dropmarker[open="true"] {
background-image: radial-gradient(circle closest-side, hsla(205,100%,70%,.1), transparent);
-moz-image-region: rect(0px, 33px, 14px, 22px);
-moz-image-region: var(--urlbar-dropmarker-active-region);
}
/* page proxy icon */

Просмотреть файл

@ -30,8 +30,8 @@
#BMB_bookmarksPopup menupopup[placespopup=true] > hbox {
/* emulating chrome://browser/content/places/menu.xml#places-popup-arrow but without the arrow */
box-shadow: 0 0 4px rgba(0,0,0,0.2);
background: #FFF;
border: 1px solid rgba(0,0,0,0.25);
background: var(--panel-arrowcontent-background);
border: var(--panel-arrowcontent-border);
border-radius: 3.5px;
margin-top: -4px;
}

Просмотреть файл

@ -2,6 +2,10 @@
* 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/. */
.searchbar-dropmarker-image {
--searchbar-dropmarker-url: url("chrome://browser/skin/searchbar-dropdown-arrow.png");
}
.autocomplete-textbox-container {
-moz-box-align: stretch;
}
@ -38,7 +42,7 @@
}
.searchbar-dropmarker-image {
list-style-image: url("chrome://browser/skin/searchbar-dropdown-arrow.png");
list-style-image: var(--searchbar-dropmarker-url);
-moz-image-region: rect(0, 13px, 11px, 0);
}

Просмотреть файл

@ -240,7 +240,6 @@ if test "$OS_TARGET" = "Android" -a -z "$gonkdir"; then
fi
else
STLPORT_CPPFLAGS="-isystem $_topsrcdir/build/stlport/stlport -isystem $_topsrcdir/build/stlport/overrides -isystem $android_ndk/sources/cxx-stl/system/include"
STLPORT_LIBS="$_objdir/build/stlport/libstlport_static.a -static-libstdc++"
fi
fi
CXXFLAGS="$CXXFLAGS $STLPORT_CPPFLAGS"

Просмотреть файл

@ -4,7 +4,13 @@
# 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/.
Library('stlport_static')
Library('stlport')
# Keep the same name as the NDK-provided library, while using a shorter
# name for the Library for convenience in moz.build.
STATIC_LIBRARY_NAME = 'stlport_static'
if not CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
OS_LIBS += ['-static-libstdc++']
FORCE_STATIC_LIB = True

Просмотреть файл

@ -5,19 +5,31 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
@template
def StdCppCompat():
'''Template for libstdc++ compatibility for target binaries.'''
def Binary():
'''Generic template for target binaries. Meant to be used by other
templates.'''
if CONFIG['MOZ_LIBSTDCXX_TARGET_VERSION']:
USE_LIBS += ['stdc++compat']
# Ideally, we'd support not adding this to the LIB_IS_C_ONLY case,
# but that variable is actually only set in db/sqlite/src, which
# doesn't build a shared library on the relevant platforms anyways.
# Eventually, though, we should detect LIB_IS_C_ONLY based on the
# associated SOURCES (and there might actually be places where we
# haven't set it but should have).
if CONFIG['STLPORT_LIBS']:
OS_LIBS += [CONFIG['STLPORT_LIBS']]
elif CONFIG['OS_TARGET'] == 'Android':
USE_LIBS += ['stlport']
@template
def Program(name):
'''Template for program executables.'''
PROGRAM = name
StdCppCompat()
Binary()
@template
@ -29,7 +41,7 @@ def SimplePrograms(names, ext='.cpp'):
SIMPLE_PROGRAMS += names
SOURCES += ['%s%s' % (name, ext) for name in names]
StdCppCompat()
Binary()
@template
@ -41,7 +53,7 @@ def CppUnitTests(names, ext='.cpp'):
CPP_UNIT_TESTS += names
SOURCES += ['%s%s' % (name, ext) for name in names]
StdCppCompat()
Binary()
@template
@ -57,7 +69,7 @@ def SharedLibrary(name):
FORCE_SHARED_LIB = True
StdCppCompat()
Binary()
@template

Просмотреть файл

@ -1,35 +0,0 @@
#!env perl
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
use File::Spec::Unix;
use strict;
print "Usage: $0 dest_path start_path\n" if ($#ARGV+1 != 2);
my $finish = my_canonpath(shift);
my $start = my_canonpath(shift);
my $res = File::Spec::Unix->abs2rel($finish, $start);
#print STDERR "abs2rel($finish,$start) = $res\n";
print "$res\n";
sub my_canonpath($) {
my ($file) = @_;
my (@inlist, @outlist, $dir);
# Do what File::Spec::Unix->no_upwards should do
my @inlist = split(/\//, File::Spec::Unix->canonpath($file));
foreach $dir (@inlist) {
if ($dir eq '..') {
pop @outlist;
} else {
push @outlist, $dir;
}
}
$file = join '/',@outlist;
return $file;
}

Просмотреть файл

@ -19,7 +19,7 @@ interface nsILoadContext;
[ptr] native JSContextPtr(JSContext);
[ptr] native JSObjectPtr(JSObject);
[scriptable, uuid(3b021962-975e-43b5-8a93-9fc2d20346e9)]
[scriptable, uuid(f649959d-dae3-4027-83fd-5b7f8c8a8815)]
interface nsIScriptSecurityManager : nsISupports
{
/**
@ -178,13 +178,6 @@ interface nsIScriptSecurityManager : nsISupports
*/
[deprecated] nsIPrincipal getCodebasePrincipal(in nsIURI uri);
/**
* Returns OK if aJSContext and target have the same "origin"
* (scheme, host, and port).
*/
[noscript] void checkSameOrigin(in JSContextPtr aJSContext,
in nsIURI aTargetURI);
/**
* Returns OK if aSourceURI and target have the same "origin"
* (scheme, host, and port).

Просмотреть файл

@ -346,6 +346,17 @@ nsPrincipal::CheckMayLoad(nsIURI* aURI, bool aReport, bool aAllowIfInheritsPrinc
}
}
// See if aURI is something like a Blob URI that is actually associated with
// a principal.
nsCOMPtr<nsIURIWithPrincipal> uriWithPrin = do_QueryInterface(aURI);
nsCOMPtr<nsIPrincipal> uriPrin;
if (uriWithPrin) {
uriWithPrin->GetPrincipal(getter_AddRefs(uriPrin));
}
if (uriPrin && nsIPrincipal::Subsumes(uriPrin)) {
return NS_OK;
}
if (nsScriptSecurityManager::SecurityCompareURIs(mCodebase, aURI)) {
return NS_OK;
}

Просмотреть файл

@ -441,39 +441,6 @@ nsScriptSecurityManager::JSPrincipalsSubsume(JSPrincipals *first,
return nsJSPrincipals::get(first)->Subsumes(nsJSPrincipals::get(second));
}
NS_IMETHODIMP
nsScriptSecurityManager::CheckSameOrigin(JSContext* cx,
nsIURI* aTargetURI)
{
MOZ_ASSERT_IF(cx, cx == nsContentUtils::GetCurrentJSContext());
// Get a principal from the context
nsIPrincipal* sourcePrincipal = nsContentUtils::SubjectPrincipal();
if (sourcePrincipal == mSystemPrincipal)
{
// This is a system (chrome) script, so allow access
return NS_OK;
}
// Get the original URI from the source principal.
// This has the effect of ignoring any change to document.domain
// which must be done to avoid DNS spoofing (bug 154930)
nsCOMPtr<nsIURI> sourceURI;
sourcePrincipal->GetDomain(getter_AddRefs(sourceURI));
if (!sourceURI) {
sourcePrincipal->GetURI(getter_AddRefs(sourceURI));
NS_ENSURE_TRUE(sourceURI, NS_ERROR_FAILURE);
}
// Compare origins
if (!SecurityCompareURIs(sourceURI, aTargetURI))
{
ReportError(cx, NS_LITERAL_STRING("CheckSameOriginError"), sourceURI, aTargetURI);
return NS_ERROR_DOM_BAD_URI;
}
return NS_OK;
}
NS_IMETHODIMP
nsScriptSecurityManager::CheckSameOriginURI(nsIURI* aSourceURI,
nsIURI* aTargetURI,

Просмотреть файл

@ -1,111 +0,0 @@
#!/usr/bin/perl -w
# 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/.
#
# Create a mapping from symbolic component name to directory name(s).
#
# Tue Oct 16 16:48:36 PDT 2001
# <mcafee@netscape.com>
use strict;
# For --option1, --option2, ...
use Getopt::Long;
Getopt::Long::Configure("bundling_override");
Getopt::Long::Configure("auto_abbrev");
# Globals
my $list_only_mode = 0;
my $opt_list_only;
my $mapfile = "";
my %map;
sub PrintUsage {
die <<END_USAGE
Prints out directories needed for a given list of components.
usage: module2dir.pl [--list-only] [--mapfile mapfile] <component-name1> <component-name2> ...
END_USAGE
}
sub parse_map_file($) {
my ($mapfile) = @_;
my (%mod_map, $tmp, $dir, $mod, @mod_list);
undef %mod_map;
open (MAPFILE, "$mapfile") || die ("$mapfile: $!\n");
while ($tmp=<MAPFILE>) {
chomp ($tmp);
($dir, $mod, @mod_list) = split(/:/, $tmp, 3);
$mod =~ s/[\s]*(\S+)[\s]*/$1/;
$mod_map{$mod} .= "$dir ";
}
close(MAPFILE);
foreach $mod (sort(keys %mod_map)) {
my (@dirlist, @trimlist, $found, $tdir);
@dirlist = split(/\s+/, $mod_map{$mod});
$mod_map{$mod} = "";
foreach $dir (@dirlist) {
$found = 0;
foreach $tdir (@trimlist) {
$found++, last if ($dir =~ m/^$tdir\// || $dir eq $tdir);
}
push @trimlist, $dir if (!$found);
}
$map{$mod} = join(" ", @trimlist);
#print "$mod: $map{$mod}\n";
}
}
sub dir_for_required_component {
my ($component) = @_;
my $rv;
my $dir;
$dir = $map{$component};
if($dir) {
# prepend "mozilla/" in front of directory names.
$rv = "mozilla/$dir";
$rv =~ s/\s+/ mozilla\//g; # Hack for 2 or more directories.
} else {
$rv = 0;
}
return $rv;
}
{
# Add stdin to the commandline. This makes commandline-only mode hang,
# call it a bug. Not sure how to get around this.
push (@ARGV, split(' ',<STDIN>));
PrintUsage() if !GetOptions('list-only' => \$opt_list_only,
'mapfile=s' => \$mapfile);
# Pick up arguments, if any.
if($opt_list_only) {
$list_only_mode = 1;
}
&parse_map_file($mapfile);
my $arg;
my $dir;
while ($arg = shift @ARGV) {
$dir = dir_for_required_component($arg);
if($dir) {
if($list_only_mode) {
print $dir, " ";
} else {
print "$arg: ", $dir, "\n";
}
} else {
# do nothing
}
}
if($dir && $list_only_mode) {
print "\n";
}
}

Просмотреть файл

@ -155,13 +155,8 @@ ifdef MOZ_LDAP_XPCOM
ldap/target: config/external/nss/target mozglue/build/target
toolkit/library/target: ldap/target
endif
ifndef MOZ_FOLD_LIBS
ifndef MOZ_NATIVE_SQLITE
config/external/nss/target: db/sqlite3/src/target
endif
endif
ifeq ($(MOZ_REPLACE_MALLOC_LINKAGE),dummy library)
mozglue/build/target: memory/replace/dummy/target
mozglue/build/target memory/replace/logalloc/replay/target: memory/replace/dummy/target
endif
endif

Просмотреть файл

@ -696,7 +696,7 @@ ifdef MOZ_PROFILE_GENERATE
touch -t `date +%Y%m%d%H%M.%S -d 'now+5seconds'` pgo.relink
endif
else # !WINNT || GNU_CC
$(EXPAND_CCC) -o $@ $(CXXFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(STATIC_LIBS) $(MOZ_PROGRAM_LDFLAGS) $(SHARED_LIBS) $(EXTRA_LIBS) $(OS_LIBS) $(BIN_FLAGS) $(EXE_DEF_FILE) $(STLPORT_LIBS)
$(EXPAND_CCC) -o $@ $(CXXFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(STATIC_LIBS) $(MOZ_PROGRAM_LDFLAGS) $(SHARED_LIBS) $(EXTRA_LIBS) $(OS_LIBS) $(BIN_FLAGS) $(EXE_DEF_FILE)
$(call CHECK_BINARY,$@)
endif # WINNT && !GNU_CC
@ -752,7 +752,7 @@ ifdef MSMANIFEST_TOOL
fi
endif # MSVC with manifest tool
else
$(EXPAND_CCC) $(CXXFLAGS) -o $@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(STATIC_LIBS) $(MOZ_PROGRAM_LDFLAGS) $(SHARED_LIBS) $(EXTRA_LIBS) $(OS_LIBS) $(BIN_FLAGS) $(STLPORT_LIBS)
$(EXPAND_CCC) $(CXXFLAGS) -o $@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(STATIC_LIBS) $(MOZ_PROGRAM_LDFLAGS) $(SHARED_LIBS) $(EXTRA_LIBS) $(OS_LIBS) $(BIN_FLAGS)
$(call CHECK_BINARY,$@)
endif # WINNT && !GNU_CC
@ -834,10 +834,10 @@ ifdef DTRACE_LIB_DEPENDENT
ifndef XP_MACOSX
dtrace -G -C -s $(MOZILLA_DTRACE_SRC) -o $(DTRACE_PROBE_OBJ) $(shell $(EXPAND_LIBS) $(MOZILLA_PROBE_LIBS))
endif
$(EXPAND_MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(SUB_SHLOBJS) $(DTRACE_PROBE_OBJ) $(MOZILLA_PROBE_LIBS) $(RESFILE) $(LDFLAGS) $(WRAP_LDFLAGS) $(STATIC_LIBS) $(SHARED_LIBS) $(EXTRA_DSO_LDOPTS) $(MOZ_GLUE_LDFLAGS) $(EXTRA_LIBS) $(OS_LIBS) $(SHLIB_LDENDFILE) $(if $(LIB_IS_C_ONLY),,$(STLPORT_LIBS))
$(EXPAND_MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(SUB_SHLOBJS) $(DTRACE_PROBE_OBJ) $(MOZILLA_PROBE_LIBS) $(RESFILE) $(LDFLAGS) $(WRAP_LDFLAGS) $(STATIC_LIBS) $(SHARED_LIBS) $(EXTRA_DSO_LDOPTS) $(MOZ_GLUE_LDFLAGS) $(EXTRA_LIBS) $(OS_LIBS) $(SHLIB_LDENDFILE)
@$(RM) $(DTRACE_PROBE_OBJ)
else # ! DTRACE_LIB_DEPENDENT
$(EXPAND_MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(SUB_SHLOBJS) $(RESFILE) $(LDFLAGS) $(WRAP_LDFLAGS) $(STATIC_LIBS) $(SHARED_LIBS) $(EXTRA_DSO_LDOPTS) $(MOZ_GLUE_LDFLAGS) $(EXTRA_LIBS) $(OS_LIBS) $(SHLIB_LDENDFILE) $(if $(LIB_IS_C_ONLY),,$(STLPORT_LIBS))
$(EXPAND_MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(SUB_SHLOBJS) $(RESFILE) $(LDFLAGS) $(WRAP_LDFLAGS) $(STATIC_LIBS) $(SHARED_LIBS) $(EXTRA_DSO_LDOPTS) $(MOZ_GLUE_LDFLAGS) $(EXTRA_LIBS) $(OS_LIBS) $(SHLIB_LDENDFILE)
endif # DTRACE_LIB_DEPENDENT
$(call CHECK_BINARY,$@)

Просмотреть файл

@ -229,7 +229,6 @@ if test -n "$gonkdir" ; then
AC_MSG_ERROR([Couldn't find path to stlport sources in the gonk tree])
fi
STLPORT_CPPFLAGS="-I$_topsrcdir/build/stlport/stlport -I$gonkdir/ndk/sources/cxx-stl/system/include"
STLPORT_LIBS="$_objdir/build/stlport/libstlport_static.a"
case "$target_cpu" in
arm)
@ -9060,8 +9059,6 @@ HAVE_SYS_VFS_H
HAVE_SYS_MOUNT_H
"
AC_SUBST(STLPORT_LIBS)
dnl ========================================================
dnl ICU Support
dnl ========================================================

Просмотреть файл

@ -53,8 +53,9 @@
var s2 = snapshotWindow($("f2").contentWindow);
var s3 = snapshotWindow($("f3").contentWindow);
ok(!compareSnapshots(s2, s3, true)[0],
"Should look different due to different sizing");
// This test is broken - see bug 1090274
//ok(!compareSnapshots(s2, s3, true)[0],
// "Should look different due to different sizing");
function getDOM(id) {
return $(id).contentDocument.documentElement.innerHTML;

Просмотреть файл

@ -70,6 +70,7 @@
#include "mozIThirdPartyUtil.h"
#ifdef MOZ_MEDIA_NAVIGATOR
#include "mozilla/dom/MediaDevices.h"
#include "MediaManager.h"
#endif
#ifdef MOZ_B2G_BT
@ -1219,6 +1220,21 @@ Navigator::SendBeacon(const nsAString& aUrl,
}
#ifdef MOZ_MEDIA_NAVIGATOR
MediaDevices*
Navigator::GetMediaDevices(ErrorResult& aRv)
{
if (!mMediaDevices) {
if (!mWindow ||
!mWindow->GetOuterWindow() ||
mWindow->GetOuterWindow()->GetCurrentInnerWindow() != mWindow) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return nullptr;
}
mMediaDevices = new MediaDevices(mWindow);
}
return mMediaDevices;
}
void
Navigator::MozGetUserMedia(const MediaStreamConstraints& aConstraints,
NavigatorUserMediaSuccessCallback& aOnSuccess,

Просмотреть файл

@ -32,6 +32,7 @@ namespace mozilla {
namespace dom {
class Geolocation;
class systemMessageCallback;
class MediaDevices;
struct MediaStreamConstraints;
class WakeLock;
class ArrayBufferViewOrBlobOrStringOrFormData;
@ -226,6 +227,7 @@ public:
TVManager* GetTv();
network::Connection* GetConnection(ErrorResult& aRv);
nsDOMCameraManager* GetMozCameras(ErrorResult& aRv);
MediaDevices* GetMediaDevices(ErrorResult& aRv);
void MozSetMessageHandler(const nsAString& aType,
systemMessageCallback* aCallback,
ErrorResult& aRv);
@ -349,6 +351,7 @@ private:
nsRefPtr<system::AudioChannelManager> mAudioChannelManager;
#endif
nsRefPtr<nsDOMCameraManager> mCameraManager;
nsRefPtr<MediaDevices> mMediaDevices;
nsCOMPtr<nsIDOMNavigatorSystemMessages> mMessagesManager;
nsTArray<nsRefPtr<nsDOMDeviceStorage> > mDeviceStorageStores;
nsRefPtr<time::TimeManager> mTimeManager;

Просмотреть файл

@ -46,7 +46,6 @@
#include "mozilla/dom/quota/FileStreams.h"
#include "mozilla/dom/quota/OriginOrPatternString.h"
#include "mozilla/dom/quota/QuotaManager.h"
#include "mozilla/dom/quota/StoragePrivilege.h"
#include "mozilla/dom/quota/UsageInfo.h"
#include "mozilla/ipc/BackgroundParent.h"
#include "mozilla/ipc/BackgroundUtils.h"
@ -3885,7 +3884,6 @@ protected:
nsCString mOrigin;
nsCString mDatabaseId;
State mState;
StoragePrivilege mStoragePrivilege;
bool mEnforcingQuota;
const bool mDeleting;
bool mBlockedQuotaManager;
@ -8590,14 +8588,14 @@ Cursor::RecvContinue(const CursorRequestParams& aParams)
FileManager::FileManager(PersistenceType aPersistenceType,
const nsACString& aGroup,
const nsACString& aOrigin,
StoragePrivilege aPrivilege,
const nsAString& aDatabaseName)
const nsAString& aDatabaseName,
bool aEnforcingQuota)
: mPersistenceType(aPersistenceType)
, mGroup(aGroup)
, mOrigin(aOrigin)
, mPrivilege(aPrivilege)
, mDatabaseName(aDatabaseName)
, mLastFileId(0)
, mEnforcingQuota(aEnforcingQuota)
, mInvalidated(false)
{ }
@ -10436,7 +10434,6 @@ FactoryOp::FactoryOp(Factory* aFactory,
, mContentParent(Move(aContentParent))
, mCommonParams(aCommonParams)
, mState(State_Initial)
, mStoragePrivilege(mozilla::dom::quota::Content)
, mEnforcingQuota(true)
, mDeleting(aDeleting)
, mBlockedQuotaManager(false)
@ -10735,9 +10732,7 @@ FactoryOp::CheckPermission(ContentParent* aContentParent,
}
if (State_Initial == mState) {
QuotaManager::GetInfoForChrome(&mGroup, &mOrigin, &mStoragePrivilege,
nullptr);
MOZ_ASSERT(mStoragePrivilege == mozilla::dom::quota::Chrome);
QuotaManager::GetInfoForChrome(&mGroup, &mOrigin, nullptr, nullptr);
mEnforcingQuota = false;
}
@ -10789,12 +10784,10 @@ FactoryOp::CheckPermission(ContentParent* aContentParent,
if (permission != PermissionRequestBase::kPermissionDenied &&
State_Initial == mState) {
rv = QuotaManager::GetInfoFromPrincipal(principal, &mGroup, &mOrigin,
&mStoragePrivilege, nullptr);
nullptr, nullptr);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
MOZ_ASSERT(mStoragePrivilege != mozilla::dom::quota::Chrome);
}
if (permission == PermissionRequestBase::kPermissionAllowed &&
@ -11326,8 +11319,8 @@ OpenDatabaseOp::DoDatabaseWork()
fileManager = new FileManager(persistenceType,
mGroup,
mOrigin,
mStoragePrivilege,
databaseName);
databaseName,
mEnforcingQuota);
rv = fileManager->Init(fmDirectory, connection);
if (NS_WARN_IF(NS_FAILED(rv))) {
@ -12704,7 +12697,7 @@ VersionChangeOp::RunOnIOThread()
if (exists) {
int64_t fileSize;
if (mDeleteDatabaseOp->mStoragePrivilege != Chrome) {
if (mDeleteDatabaseOp->mEnforcingQuota) {
rv = dbFile->GetFileSize(&fileSize);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@ -12716,7 +12709,7 @@ VersionChangeOp::RunOnIOThread()
return rv;
}
if (mDeleteDatabaseOp->mStoragePrivilege != Chrome) {
if (mDeleteDatabaseOp->mEnforcingQuota) {
quotaManager->DecreaseUsageForOrigin(persistenceType,
mDeleteDatabaseOp->mGroup,
mDeleteDatabaseOp->mOrigin,
@ -12781,7 +12774,7 @@ VersionChangeOp::RunOnIOThread()
uint64_t usage = 0;
if (mDeleteDatabaseOp->mStoragePrivilege != Chrome) {
if (mDeleteDatabaseOp->mEnforcingQuota) {
rv = FileManager::GetUsage(fmDirectory, &usage);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@ -12793,7 +12786,7 @@ VersionChangeOp::RunOnIOThread()
return rv;
}
if (mDeleteDatabaseOp->mStoragePrivilege != Chrome) {
if (mDeleteDatabaseOp->mEnforcingQuota) {
quotaManager->DecreaseUsageForOrigin(persistenceType,
mDeleteDatabaseOp->mGroup,
mDeleteDatabaseOp->mOrigin,
@ -14425,12 +14418,14 @@ ObjectStoreAddOrPutRequestOp::CopyFileData(nsIInputStream* aInputStream,
}
} while (true);
nsresult rv2 = aOutputStream->Flush();
if (NS_WARN_IF(NS_FAILED(rv2))) {
return NS_SUCCEEDED(rv) ? rv2 : rv;
if (NS_SUCCEEDED(rv)) {
rv = aOutputStream->Flush();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
rv2 = aOutputStream->Close();
nsresult rv2 = aOutputStream->Close();
if (NS_WARN_IF(NS_FAILED(rv2))) {
return NS_SUCCEEDED(rv) ? rv2 : rv;
}
@ -14804,9 +14799,31 @@ ObjectStoreAddOrPutRequestOp::DoDatabaseWork(TransactionBase* aTransaction)
}
if (NS_WARN_IF(NS_FAILED(rv))) {
// Try to remove the file if the copy failed.
if (NS_FAILED(diskFile->Remove(false))) {
NS_WARNING("Failed to remove file after copying failed!");
nsresult rv2;
int64_t fileSize;
if (mFileManager->EnforcingQuota()) {
rv2 = diskFile->GetFileSize(&fileSize);
if (NS_WARN_IF(NS_FAILED(rv2))) {
return rv;
}
}
rv2 = diskFile->Remove(false);
if (NS_WARN_IF(NS_FAILED(rv2))) {
return rv;
}
if (mFileManager->EnforcingQuota()) {
QuotaManager* quotaManager = QuotaManager::Get();
MOZ_ASSERT(quotaManager);
quotaManager->DecreaseUsageForOrigin(mFileManager->Type(),
mFileManager->Group(),
mFileManager->Origin(),
fileSize);
}
return rv;
}

Просмотреть файл

@ -9,7 +9,6 @@
#include "mozilla/Attributes.h"
#include "mozilla/dom/quota/PersistenceType.h"
#include "mozilla/dom/quota/StoragePrivilege.h"
#include "nsDataHashtable.h"
#include "nsHashKeys.h"
#include "nsISupportsImpl.h"
@ -29,12 +28,10 @@ class FileManager MOZ_FINAL
friend class FileInfo;
typedef mozilla::dom::quota::PersistenceType PersistenceType;
typedef mozilla::dom::quota::StoragePrivilege StoragePrivilege;
PersistenceType mPersistenceType;
nsCString mGroup;
nsCString mOrigin;
StoragePrivilege mPrivilege;
nsString mDatabaseName;
nsString mDirectoryPath;
@ -45,6 +42,7 @@ class FileManager MOZ_FINAL
// Protected by IndexedDatabaseManager::FileMutex()
nsDataHashtable<nsUint64HashKey, FileInfo*> mFileInfos;
const bool mEnforcingQuota;
bool mInvalidated;
public:
@ -64,8 +62,8 @@ public:
FileManager(PersistenceType aPersistenceType,
const nsACString& aGroup,
const nsACString& aOrigin,
StoragePrivilege aPrivilege,
const nsAString& aDatabaseName);
const nsAString& aDatabaseName,
bool aEnforcingQuota);
PersistenceType
Type() const
@ -85,18 +83,18 @@ public:
return mOrigin;
}
const StoragePrivilege&
Privilege() const
{
return mPrivilege;
}
const nsAString&
DatabaseName() const
{
return mDatabaseName;
}
bool
EnforcingQuota() const
{
return mEnforcingQuota;
}
bool
Invalidated() const
{

Просмотреть файл

@ -848,7 +848,7 @@ AsyncDeleteFileRunnable::Run()
nsresult rv;
int64_t fileSize;
if (mFileManager->Privilege() != Chrome) {
if (mFileManager->EnforcingQuota()) {
rv = file->GetFileSize(&fileSize);
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
}
@ -856,7 +856,7 @@ AsyncDeleteFileRunnable::Run()
rv = file->Remove(false);
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
if (mFileManager->Privilege() != Chrome) {
if (mFileManager->EnforcingQuota()) {
QuotaManager* quotaManager = QuotaManager::Get();
NS_ASSERTION(quotaManager, "Shouldn't be null!");

Просмотреть файл

@ -12,7 +12,6 @@
#include "mozilla/dom/indexedDB/IDBCursor.h"
#include "mozilla/dom/indexedDB/IDBTransaction.h"
#include "mozilla/dom/quota/PersistenceType.h"
#include "mozilla/dom/quota/StoragePrivilege.h"
namespace IPC {
@ -24,13 +23,6 @@ struct ParamTraits<mozilla::dom::quota::PersistenceType> :
mozilla::dom::quota::PERSISTENCE_TYPE_INVALID>
{ };
template <>
struct ParamTraits<mozilla::dom::quota::StoragePrivilege> :
public ContiguousEnumSerializer<mozilla::dom::quota::StoragePrivilege,
mozilla::dom::quota::Chrome,
mozilla::dom::quota::Invalid>
{ };
template <>
struct ParamTraits<mozilla::dom::indexedDB::Key>
{

Просмотреть файл

@ -33,7 +33,12 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DOMMediaStream)
NS_INTERFACE_MAP_ENTRY(DOMMediaStream)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
NS_IMPL_ISUPPORTS_INHERITED0(DOMLocalMediaStream, DOMMediaStream)
NS_IMPL_ADDREF_INHERITED(DOMLocalMediaStream, DOMMediaStream)
NS_IMPL_RELEASE_INHERITED(DOMLocalMediaStream, DOMMediaStream)
NS_INTERFACE_MAP_BEGIN(DOMLocalMediaStream)
NS_INTERFACE_MAP_ENTRY(DOMLocalMediaStream)
NS_INTERFACE_MAP_END_INHERITING(DOMMediaStream)
NS_IMPL_CYCLE_COLLECTION_INHERITED(DOMAudioNodeMediaStream, DOMMediaStream,
mStreamNode)

Просмотреть файл

@ -20,15 +20,10 @@ namespace mozilla {
#ifdef PR_LOGGING
extern PRLogModuleInfo* gMediaDecoderLog;
#define DECODER_LOG(type, msg) PR_LOG(gMediaDecoderLog, type, msg)
#ifdef SEEK_LOGGING
#define SEEK_LOG(type, msg) PR_LOG(gMediaDecoderLog, type, msg)
#define DECODER_LOG(x, ...) \
PR_LOG(gMediaDecoderLog, PR_LOG_DEBUG, ("Decoder=%p " x, mDecoder, ##__VA_ARGS__))
#else
#define SEEK_LOG(type, msg)
#endif
#else
#define DECODER_LOG(type, msg)
#define SEEK_LOG(type, msg)
#define DECODER_LOG(x, ...)
#endif
class VideoQueueMemoryFunctor : public nsDequeFunctor {
@ -139,6 +134,20 @@ MediaDecoderReader::GetBuffered(mozilla::dom::TimeRanges* aBuffered,
return NS_OK;
}
int64_t
MediaDecoderReader::ComputeStartTime(const VideoData* aVideo, const AudioData* aAudio)
{
int64_t startTime = std::min<int64_t>(aAudio ? aAudio->mTime : INT64_MAX,
aVideo ? aVideo->mTime : INT64_MAX);
if (startTime == INT64_MAX) {
startTime = 0;
}
DECODER_LOG("ComputeStartTime first video frame start %lld", aVideo ? aVideo->mTime : -1);
DECODER_LOG("ComputeStartTime first audio frame start %lld", aAudio ? aAudio->mTime : -1);
MOZ_ASSERT(startTime >= 0);
return startTime;
}
class RequestVideoWithSkipTask : public nsRunnable {
public:
RequestVideoWithSkipTask(MediaDecoderReader* aReader,

Просмотреть файл

@ -148,6 +148,8 @@ public:
virtual nsresult GetBuffered(dom::TimeRanges* aBuffered,
int64_t aStartTime);
virtual int64_t ComputeStartTime(const VideoData* aVideo, const AudioData* aAudio);
// Returns the number of bytes of memory allocated by structures/frames in
// the video queue.
size_t SizeOfVideoQueueInBytes() const;

Просмотреть файл

@ -2016,18 +2016,9 @@ MediaDecoderStateMachine::FinishDecodeMetadata()
}
if (!mScheduler->IsRealTime() && !mDecodingFrozenAtStateMetadata) {
const VideoData* v = VideoQueue().PeekFront();
const AudioData* a = AudioQueue().PeekFront();
int64_t startTime = std::min<int64_t>(a ? a->mTime : INT64_MAX,
v ? v->mTime : INT64_MAX);
if (startTime == INT64_MAX) {
startTime = 0;
}
DECODER_LOG("DecodeMetadata first video frame start %lld", v ? v->mTime : -1);
DECODER_LOG("DecodeMetadata first audio frame start %lld", a ? a->mTime : -1);
SetStartTime(startTime);
SetStartTime(mReader->ComputeStartTime(v, a));
if (VideoQueue().GetSize()) {
ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
RenderVideoFrame(VideoQueue().PeekFront(), TimeStamp::Now());

Просмотреть файл

@ -0,0 +1,97 @@
/* 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 "mozilla/dom/MediaDevices.h"
#include "mozilla/dom/MediaStreamBinding.h"
#include "mozilla/dom/MediaDevicesBinding.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/MediaManager.h"
#include "nsIEventTarget.h"
#include "nsIScriptGlobalObject.h"
#include "nsPIDOMWindow.h"
namespace mozilla {
namespace dom {
class MediaDevices::GumResolver : public nsIDOMGetUserMediaSuccessCallback
{
public:
NS_DECL_ISUPPORTS
explicit GumResolver(Promise* aPromise) : mPromise(aPromise) {}
NS_IMETHOD
OnSuccess(nsISupports* aStream) MOZ_OVERRIDE
{
nsRefPtr<DOMLocalMediaStream> stream = do_QueryObject(aStream);
if (!stream) {
return NS_ERROR_FAILURE;
}
mPromise->MaybeResolve(stream);
return NS_OK;
}
private:
virtual ~GumResolver() {}
nsRefPtr<Promise> mPromise;
};
class MediaDevices::GumRejecter : public nsIDOMGetUserMediaErrorCallback
{
public:
NS_DECL_ISUPPORTS
explicit GumRejecter(Promise* aPromise) : mPromise(aPromise) {}
NS_IMETHOD
OnError(nsISupports* aError) MOZ_OVERRIDE
{
nsRefPtr<MediaStreamError> error = do_QueryObject(aError);
if (!error) {
return NS_ERROR_FAILURE;
}
mPromise->MaybeReject(error);
return NS_OK;
}
private:
virtual ~GumRejecter() {}
nsRefPtr<Promise> mPromise;
};
NS_IMPL_ISUPPORTS(MediaDevices::GumResolver, nsIDOMGetUserMediaSuccessCallback)
NS_IMPL_ISUPPORTS(MediaDevices::GumRejecter, nsIDOMGetUserMediaErrorCallback)
already_AddRefed<Promise>
MediaDevices::GetUserMedia(const MediaStreamConstraints& aConstraints,
ErrorResult &aRv)
{
ErrorResult rv;
nsPIDOMWindow* window = GetOwner();
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(window);
nsRefPtr<Promise> p = Promise::Create(go, aRv);
NS_ENSURE_TRUE(!rv.Failed(), nullptr);
nsRefPtr<GumResolver> resolver = new GumResolver(p);
nsRefPtr<GumRejecter> rejecter = new GumRejecter(p);
aRv = MediaManager::Get()->GetUserMedia(window, aConstraints,
resolver, rejecter);
return p.forget();
}
NS_IMPL_ADDREF_INHERITED(MediaDevices, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(MediaDevices, DOMEventTargetHelper)
NS_INTERFACE_MAP_BEGIN(MediaDevices)
NS_INTERFACE_MAP_ENTRY(MediaDevices)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
JSObject*
MediaDevices::WrapObject(JSContext* aCx)
{
return MediaDevicesBinding::Wrap(aCx, this);
}
} // namespace dom
} // namespace mozilla

50
dom/media/MediaDevices.h Normal file
Просмотреть файл

@ -0,0 +1,50 @@
/* 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 MediaDevices_h__
#define MediaDevices_h__
#include "mozilla/ErrorResult.h"
#include "nsISupportsImpl.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/dom/BindingUtils.h"
#include "nsPIDOMWindow.h"
namespace mozilla {
namespace dom {
class Promise;
struct MediaStreamConstraints;
#define MOZILLA_DOM_MEDIADEVICES_IMPLEMENTATION_IID \
{ 0x2f784d8a, 0x7485, 0x4280, \
{ 0x9a, 0x36, 0x74, 0xa4, 0xd6, 0x71, 0xa6, 0xc8 } }
class MediaDevices MOZ_FINAL : public DOMEventTargetHelper
{
public:
MediaDevices(nsPIDOMWindow* aWindow) : DOMEventTargetHelper(aWindow) {}
NS_DECL_ISUPPORTS_INHERITED
NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_DOM_MEDIADEVICES_IMPLEMENTATION_IID)
JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
already_AddRefed<Promise>
GetUserMedia(const MediaStreamConstraints& aConstraints, ErrorResult &aRv);
private:
class GumResolver;
class GumRejecter;
virtual ~MediaDevices() {}
};
NS_DEFINE_STATIC_IID_ACCESSOR(MediaDevices,
MOZILLA_DOM_MEDIADEVICES_IMPLEMENTATION_IID)
} // namespace dom
} // namespace mozilla
#endif // MediaDevices_h__

Просмотреть файл

@ -102,6 +102,7 @@ GetMediaManagerLog()
using dom::MediaStreamConstraints; // Outside API (contains JSObject)
using dom::MediaTrackConstraintSet; // Mandatory or optional constraints
using dom::MediaTrackConstraints; // Raw mMandatory (as JSObject)
using dom::MediaStreamError;
using dom::GetUserMediaRequest;
using dom::Sequence;
using dom::OwningBooleanOrMediaTrackConstraints;
@ -194,20 +195,21 @@ HostHasPermission(nsIURI &docURI)
}
ErrorCallbackRunnable::ErrorCallbackRunnable(
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback>& aSuccess,
nsCOMPtr<nsIDOMGetUserMediaErrorCallback>& aError,
const nsAString& aErrorMsg, uint64_t aWindowID)
: mErrorMsg(aErrorMsg)
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback>& aOnSuccess,
nsCOMPtr<nsIDOMGetUserMediaErrorCallback>& aOnFailure,
MediaMgrError& aError,
uint64_t aWindowID)
: mError(&aError)
, mWindowID(aWindowID)
, mManager(MediaManager::GetInstance())
{
mSuccess.swap(aSuccess);
mError.swap(aError);
mOnSuccess.swap(aOnSuccess);
mOnFailure.swap(aOnFailure);
}
ErrorCallbackRunnable::~ErrorCallbackRunnable()
{
MOZ_ASSERT(!mSuccess && !mError);
MOZ_ASSERT(!mOnSuccess && !mOnFailure);
}
NS_IMETHODIMP
@ -216,15 +218,19 @@ ErrorCallbackRunnable::Run()
// Only run if the window is still active.
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> success = mSuccess.forget();
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> error = mError.forget();
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> onSuccess = mOnSuccess.forget();
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> onFailure = mOnFailure.forget();
if (!(mManager->IsWindowStillActive(mWindowID))) {
return NS_OK;
}
// This is safe since we're on main-thread, and the windowlist can only
// be invalidated from the main-thread (see OnNavigation)
error->OnError(mErrorMsg);
nsGlobalWindow* window = nsGlobalWindow::GetInnerWindowWithId(mWindowID);
if (window) {
nsRefPtr<MediaStreamError> error = new MediaStreamError(window, *mError);
onFailure->OnError(error);
}
return NS_OK;
}
@ -238,15 +244,15 @@ class SuccessCallbackRunnable : public nsRunnable
{
public:
SuccessCallbackRunnable(
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback>& aSuccess,
nsCOMPtr<nsIDOMGetUserMediaErrorCallback>& aError,
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback>& aOnSuccess,
nsCOMPtr<nsIDOMGetUserMediaErrorCallback>& aOnFailure,
nsIDOMFile* aFile, uint64_t aWindowID)
: mFile(aFile)
, mWindowID(aWindowID)
, mManager(MediaManager::GetInstance())
{
mSuccess.swap(aSuccess);
mError.swap(aError);
mOnSuccess.swap(aOnSuccess);
mOnFailure.swap(aOnFailure);
}
NS_IMETHOD
@ -255,21 +261,21 @@ public:
// Only run if the window is still active.
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> success = mSuccess.forget();
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> error = mError.forget();
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> onSuccess = mOnSuccess.forget();
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> onFailure = mOnFailure.forget();
if (!(mManager->IsWindowStillActive(mWindowID))) {
return NS_OK;
}
// This is safe since we're on main-thread, and the windowlist can only
// be invalidated from the main-thread (see OnNavigation)
success->OnSuccess(mFile);
onSuccess->OnSuccess(mFile);
return NS_OK;
}
private:
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> mSuccess;
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> mError;
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> mOnSuccess;
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> mOnFailure;
nsCOMPtr<nsIDOMFile> mFile;
uint64_t mWindowID;
nsRefPtr<MediaManager> mManager; // get ref to this when creating the runnable
@ -285,15 +291,15 @@ class DeviceSuccessCallbackRunnable: public nsRunnable
public:
DeviceSuccessCallbackRunnable(
uint64_t aWindowID,
nsCOMPtr<nsIGetUserMediaDevicesSuccessCallback>& aSuccess,
nsCOMPtr<nsIDOMGetUserMediaErrorCallback>& aError,
nsCOMPtr<nsIGetUserMediaDevicesSuccessCallback>& aOnSuccess,
nsCOMPtr<nsIDOMGetUserMediaErrorCallback>& aOnFailure,
nsTArray<nsRefPtr<MediaDevice>>* aDevices)
: mDevices(aDevices)
, mWindowID(aWindowID)
, mManager(MediaManager::GetInstance())
{
mSuccess.swap(aSuccess);
mError.swap(aError);
mOnSuccess.swap(aOnSuccess);
mOnFailure.swap(aOnFailure);
}
NS_IMETHOD
@ -315,7 +321,12 @@ public:
// We should in the future return an empty array, and dynamically add
// devices to the dropdowns if things are hotplugged while the
// requester is up.
mError->OnError(NS_LITERAL_STRING("NO_DEVICES_FOUND"));
nsGlobalWindow* window = nsGlobalWindow::GetInnerWindowWithId(mWindowID);
if (window) {
nsRefPtr<MediaStreamError> error = new MediaStreamError(window,
NS_LITERAL_STRING("NotFoundError"));
mOnFailure->OnError(error);
}
return NS_OK;
}
@ -331,13 +342,13 @@ public:
static_cast<const void*>(tmp.Elements())
));
mSuccess->OnSuccess(devices);
mOnSuccess->OnSuccess(devices);
return NS_OK;
}
private:
nsCOMPtr<nsIGetUserMediaDevicesSuccessCallback> mSuccess;
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> mError;
nsCOMPtr<nsIGetUserMediaDevicesSuccessCallback> mOnSuccess;
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> mOnFailure;
nsAutoPtr<nsTArray<nsRefPtr<MediaDevice>>> mDevices;
uint64_t mWindowID;
nsRefPtr<MediaManager> mManager;
@ -723,8 +734,8 @@ class GetUserMediaStreamRunnable : public nsRunnable
{
public:
GetUserMediaStreamRunnable(
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback>& aSuccess,
nsCOMPtr<nsIDOMGetUserMediaErrorCallback>& aError,
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback>& aOnSuccess,
nsCOMPtr<nsIDOMGetUserMediaErrorCallback>& aOnFailure,
uint64_t aWindowID,
GetUserMediaCallbackMediaStreamListener* aListener,
MediaEngineSource* aAudioSource,
@ -737,8 +748,8 @@ public:
, mPeerIdentity(aPeerIdentity)
, mManager(MediaManager::GetInstance())
{
mSuccess.swap(aSuccess);
mError.swap(aError);
mOnSuccess.swap(aOnSuccess);
mOnFailure.swap(aOnFailure);
}
~GetUserMediaStreamRunnable() {}
@ -750,7 +761,7 @@ public:
nsIDOMGetUserMediaSuccessCallback* aSuccess,
uint64_t aWindowID,
DOMMediaStream* aStream)
: mWindowID(aWindowID), mSuccess(aSuccess), mManager(aManager),
: mWindowID(aWindowID), mOnSuccess(aSuccess), mManager(aManager),
mStream(aStream) {}
virtual void NotifyTracksAvailable(DOMMediaStream* aStream) MOZ_OVERRIDE
{
@ -766,10 +777,10 @@ public:
// This is safe since we're on main-thread, and the windowlist can only
// be invalidated from the main-thread (see OnNavigation)
LOG(("Returning success for getUserMedia()"));
mSuccess->OnSuccess(aStream);
mOnSuccess->OnSuccess(aStream);
}
uint64_t mWindowID;
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> mSuccess;
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> mOnSuccess;
nsRefPtr<MediaManager> mManager;
// Keep the DOMMediaStream alive until the NotifyTracksAvailable callback
// has fired, otherwise we might immediately destroy the DOMMediaStream and
@ -830,9 +841,16 @@ public:
nsDOMUserMediaStream::CreateTrackUnionStream(window, mListener,
mAudioSource, mVideoSource);
if (!trackunion) {
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> error = mError.forget();
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> onFailure = mOnFailure.forget();
LOG(("Returning error for getUserMedia() - no stream"));
error->OnError(NS_LITERAL_STRING("NO_STREAM"));
nsGlobalWindow* window = nsGlobalWindow::GetInnerWindowWithId(mWindowID);
if (window) {
nsRefPtr<MediaStreamError> error = new MediaStreamError(window,
NS_LITERAL_STRING("InternalError"),
NS_LITERAL_STRING("No stream."));
onFailure->OnError(error);
}
return NS_OK;
}
trackunion->AudioConfig(aec_on, (uint32_t) aec,
@ -874,7 +892,7 @@ public:
// Note: includes JS callbacks; must be released on MainThread
TracksAvailableCallback* tracksAvailableCallback =
new TracksAvailableCallback(mManager, mSuccess, mWindowID, trackunion);
new TracksAvailableCallback(mManager, mOnSuccess, mWindowID, trackunion);
mListener->AudioConfig(aec_on, (uint32_t) aec,
agc_on, (uint32_t) agc,
@ -889,16 +907,16 @@ public:
new MediaOperationTask(MEDIA_START, mListener, trackunion,
tracksAvailableCallback,
mAudioSource, mVideoSource, false, mWindowID,
mError.forget()));
mOnFailure.forget()));
// We won't need mError now.
mError = nullptr;
// We won't need mOnFailure now.
mOnFailure = nullptr;
return NS_OK;
}
private:
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> mSuccess;
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> mError;
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> mOnSuccess;
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> mOnFailure;
nsRefPtr<MediaEngineSource> mAudioSource;
nsRefPtr<MediaEngineSource> mVideoSource;
uint64_t mWindowID;
@ -1056,13 +1074,13 @@ class GetUserMediaTask : public Task
public:
GetUserMediaTask(
const MediaStreamConstraints& aConstraints,
already_AddRefed<nsIDOMGetUserMediaSuccessCallback> aSuccess,
already_AddRefed<nsIDOMGetUserMediaErrorCallback> aError,
already_AddRefed<nsIDOMGetUserMediaSuccessCallback> aOnSuccess,
already_AddRefed<nsIDOMGetUserMediaErrorCallback> aOnFailure,
uint64_t aWindowID, GetUserMediaCallbackMediaStreamListener *aListener,
MediaEnginePrefs &aPrefs)
: mConstraints(aConstraints)
, mSuccess(aSuccess)
, mError(aError)
, mOnSuccess(aOnSuccess)
, mOnFailure(aOnFailure)
, mWindowID(aWindowID)
, mListener(aListener)
, mPrefs(aPrefs)
@ -1077,14 +1095,14 @@ public:
*/
GetUserMediaTask(
const MediaStreamConstraints& aConstraints,
already_AddRefed<nsIDOMGetUserMediaSuccessCallback> aSuccess,
already_AddRefed<nsIDOMGetUserMediaErrorCallback> aError,
already_AddRefed<nsIDOMGetUserMediaSuccessCallback> aOnSuccess,
already_AddRefed<nsIDOMGetUserMediaErrorCallback> aOnFailure,
uint64_t aWindowID, GetUserMediaCallbackMediaStreamListener *aListener,
MediaEnginePrefs &aPrefs,
MediaEngine* aBackend)
: mConstraints(aConstraints)
, mSuccess(aSuccess)
, mError(aError)
, mOnSuccess(aOnSuccess)
, mOnFailure(aOnFailure)
, mWindowID(aWindowID)
, mListener(aListener)
, mPrefs(aPrefs)
@ -1097,12 +1115,14 @@ public:
}
void
Fail(const nsAString& aMessage) {
Fail(const nsAString& aName,
const nsAString& aMessage = EmptyString()) {
nsRefPtr<MediaMgrError> error = new MediaMgrError(aName, aMessage);
nsRefPtr<ErrorCallbackRunnable> runnable =
new ErrorCallbackRunnable(mSuccess, mError, aMessage, mWindowID);
new ErrorCallbackRunnable(mOnSuccess, mOnFailure, *error, mWindowID);
// These should be empty now
MOZ_ASSERT(!mSuccess);
MOZ_ASSERT(!mError);
MOZ_ASSERT(!mOnSuccess);
MOZ_ASSERT(!mOnFailure);
NS_DispatchToMainThread(runnable);
}
@ -1111,8 +1131,8 @@ public:
Run()
{
NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
MOZ_ASSERT(mSuccess);
MOZ_ASSERT(mError);
MOZ_ASSERT(mOnSuccess);
MOZ_ASSERT(mOnFailure);
MediaEngine* backend = mBackend;
// Was a backend provided?
@ -1136,34 +1156,40 @@ public:
}
nsresult
Denied(const nsAString& aErrorMsg)
Denied(const nsAString& aName,
const nsAString& aMessage = EmptyString())
{
MOZ_ASSERT(mSuccess);
MOZ_ASSERT(mError);
MOZ_ASSERT(mOnSuccess);
MOZ_ASSERT(mOnFailure);
// We add a disabled listener to the StreamListeners array until accepted
// If this was the only active MediaStream, remove the window from the list.
if (NS_IsMainThread()) {
// This is safe since we're on main-thread, and the window can only
// be invalidated from the main-thread (see OnNavigation)
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> success = mSuccess.forget();
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> error = mError.forget();
error->OnError(aErrorMsg);
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> onSuccess = mOnSuccess.forget();
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> onFailure = mOnFailure.forget();
nsGlobalWindow* window = nsGlobalWindow::GetInnerWindowWithId(mWindowID);
if (window) {
nsRefPtr<MediaStreamError> error = new MediaStreamError(window,
aName, aMessage);
onFailure->OnError(error);
}
// Should happen *after* error runs for consistency, but may not matter
nsRefPtr<MediaManager> manager(MediaManager::GetInstance());
manager->RemoveFromWindowList(mWindowID, mListener);
} else {
// This will re-check the window being alive on main-thread
// Note: we must remove the listener on MainThread as well
Fail(aErrorMsg);
Fail(aName, aMessage);
// MUST happen after ErrorCallbackRunnable Run()s, as it checks the active window list
NS_DispatchToMainThread(new GetUserMediaListenerRemove(mWindowID, mListener));
}
MOZ_ASSERT(!mSuccess);
MOZ_ASSERT(!mError);
MOZ_ASSERT(!mOnSuccess);
MOZ_ASSERT(!mOnFailure);
return NS_OK;
}
@ -1194,15 +1220,15 @@ public:
nsresult
SelectDevice(MediaEngine* backend)
{
MOZ_ASSERT(mSuccess);
MOZ_ASSERT(mError);
MOZ_ASSERT(mOnSuccess);
MOZ_ASSERT(mOnFailure);
if (IsOn(mConstraints.mVideo)) {
VideoTrackConstraintsN constraints(GetInvariant(mConstraints.mVideo));
nsTArray<nsRefPtr<VideoDevice>> sources;
GetSources(backend, constraints, &MediaEngine::EnumerateVideoDevices, sources);
if (!sources.Length()) {
Fail(NS_LITERAL_STRING("NO_DEVICES_FOUND"));
Fail(NS_LITERAL_STRING("NotFoundError"));
return NS_ERROR_FAILURE;
}
// Pick the first available device.
@ -1215,7 +1241,7 @@ public:
GetSources(backend, constraints, &MediaEngine::EnumerateAudioDevices, sources);
if (!sources.Length()) {
Fail(NS_LITERAL_STRING("NO_DEVICES_FOUND"));
Fail(NS_LITERAL_STRING("NotFoundError"));
return NS_ERROR_FAILURE;
}
// Pick the first available device.
@ -1234,14 +1260,15 @@ public:
ProcessGetUserMedia(MediaEngineAudioSource* aAudioSource,
MediaEngineVideoSource* aVideoSource)
{
MOZ_ASSERT(mSuccess);
MOZ_ASSERT(mError);
MOZ_ASSERT(mOnSuccess);
MOZ_ASSERT(mOnFailure);
nsresult rv;
if (aAudioSource) {
rv = aAudioSource->Allocate(GetInvariant(mConstraints.mAudio), mPrefs);
if (NS_FAILED(rv)) {
LOG(("Failed to allocate audiosource %d",rv));
Fail(NS_LITERAL_STRING("HARDWARE_UNAVAILABLE"));
Fail(NS_LITERAL_STRING("SourceUnavailableError"),
NS_LITERAL_STRING("Failed to allocate audiosource"));
return;
}
}
@ -1252,7 +1279,8 @@ public:
if (aAudioSource) {
aAudioSource->Deallocate();
}
Fail(NS_LITERAL_STRING("HARDWARE_UNAVAILABLE"));
Fail(NS_LITERAL_STRING("SourceUnavailableError"),
NS_LITERAL_STRING("Failed to allocate videosource"));
return;
}
}
@ -1262,12 +1290,12 @@ public:
}
NS_DispatchToMainThread(new GetUserMediaStreamRunnable(
mSuccess, mError, mWindowID, mListener, aAudioSource, aVideoSource,
mOnSuccess, mOnFailure, mWindowID, mListener, aAudioSource, aVideoSource,
peerIdentity
));
MOZ_ASSERT(!mSuccess);
MOZ_ASSERT(!mError);
MOZ_ASSERT(!mOnSuccess);
MOZ_ASSERT(!mOnFailure);
return;
}
@ -1275,8 +1303,8 @@ public:
private:
MediaStreamConstraints mConstraints;
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> mSuccess;
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> mError;
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> mOnSuccess;
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> mOnFailure;
uint64_t mWindowID;
nsRefPtr<GetUserMediaCallbackMediaStreamListener> mListener;
nsRefPtr<AudioDevice> mAudioDevice;
@ -1322,13 +1350,13 @@ class GetUserMediaDevicesTask : public Task
public:
GetUserMediaDevicesTask(
const MediaStreamConstraints& aConstraints,
already_AddRefed<nsIGetUserMediaDevicesSuccessCallback> aSuccess,
already_AddRefed<nsIDOMGetUserMediaErrorCallback> aError,
already_AddRefed<nsIGetUserMediaDevicesSuccessCallback> aOnSuccess,
already_AddRefed<nsIDOMGetUserMediaErrorCallback> aOnFailure,
uint64_t aWindowId, nsACString& aAudioLoopbackDev,
nsACString& aVideoLoopbackDev)
: mConstraints(aConstraints)
, mSuccess(aSuccess)
, mError(aError)
, mOnSuccess(aOnSuccess)
, mOnFailure(aOnFailure)
, mManager(MediaManager::GetInstance())
, mWindowId(aWindowId)
, mLoopbackAudioDevice(aAudioLoopbackDev)
@ -1368,16 +1396,16 @@ public:
}
NS_DispatchToMainThread(new DeviceSuccessCallbackRunnable(mWindowId,
mSuccess, mError,
mOnSuccess, mOnFailure,
final.forget()));
// DeviceSuccessCallbackRunnable should have taken these.
MOZ_ASSERT(!mSuccess && !mError);
MOZ_ASSERT(!mOnSuccess && !mOnFailure);
}
private:
MediaStreamConstraints mConstraints;
nsCOMPtr<nsIGetUserMediaDevicesSuccessCallback> mSuccess;
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> mError;
nsCOMPtr<nsIGetUserMediaDevicesSuccessCallback> mOnSuccess;
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> mOnFailure;
nsRefPtr<MediaManager> mManager;
uint64_t mWindowId;
const nsString mCallId;
@ -1544,18 +1572,18 @@ nsresult
MediaManager::GetUserMedia(
nsPIDOMWindow* aWindow, const MediaStreamConstraints& aConstraints,
nsIDOMGetUserMediaSuccessCallback* aOnSuccess,
nsIDOMGetUserMediaErrorCallback* aOnError)
nsIDOMGetUserMediaErrorCallback* aOnFailure)
{
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
NS_ENSURE_TRUE(aWindow, NS_ERROR_NULL_POINTER);
NS_ENSURE_TRUE(aOnError, NS_ERROR_NULL_POINTER);
NS_ENSURE_TRUE(aOnFailure, NS_ERROR_NULL_POINTER);
NS_ENSURE_TRUE(aOnSuccess, NS_ERROR_NULL_POINTER);
bool privileged = nsContentUtils::IsChromeDoc(aWindow->GetExtantDoc());
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> onSuccess(aOnSuccess);
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> onError(aOnError);
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> onFailure(aOnFailure);
MediaStreamConstraints c(aConstraints); // copy
@ -1640,11 +1668,11 @@ MediaManager::GetUserMedia(
if (c.mFake) {
// Fake stream from default backend.
task = new GetUserMediaTask(c, onSuccess.forget(),
onError.forget(), windowID, listener, mPrefs, new MediaEngineDefault());
onFailure.forget(), windowID, listener, mPrefs, new MediaEngineDefault());
} else {
// Stream from default device from WebRTC backend.
task = new GetUserMediaTask(c, onSuccess.forget(),
onError.forget(), windowID, listener, mPrefs);
onFailure.forget(), windowID, listener, mPrefs);
}
nsIURI* docURI = aWindow->GetDocumentURI();
@ -1655,10 +1683,10 @@ MediaManager::GetUserMedia(
if (tc.mMediaSource != dom::MediaSourceEnum::Camera) {
if (tc.mMediaSource == dom::MediaSourceEnum::Browser) {
if (!Preferences::GetBool("media.getusermedia.browser.enabled", false)) {
return task->Denied(NS_LITERAL_STRING("PERMISSION_DENIED"));
return task->Denied(NS_LITERAL_STRING("PermissionDeniedError"));
}
} else if (!Preferences::GetBool("media.getusermedia.screensharing.enabled", false)) {
return task->Denied(NS_LITERAL_STRING("PERMISSION_DENIED"));
return task->Denied(NS_LITERAL_STRING("PermissionDeniedError"));
}
/* Deny screensharing if the requesting document is not from a host
on the whitelist. */
@ -1676,7 +1704,7 @@ MediaManager::GetUserMedia(
) ||
#endif
(!privileged && !HostHasPermission(*docURI))) {
return task->Denied(NS_LITERAL_STRING("PERMISSION_DENIED"));
return task->Denied(NS_LITERAL_STRING("PermissionDeniedError"));
}
}
}
@ -1730,7 +1758,7 @@ MediaManager::GetUserMedia(
if ((!IsOn(c.mAudio) || audioPerm == nsIPermissionManager::DENY_ACTION) &&
(!IsOn(c.mVideo) || videoPerm == nsIPermissionManager::DENY_ACTION)) {
return task->Denied(NS_LITERAL_STRING("PERMISSION_DENIED"));
return task->Denied(NS_LITERAL_STRING("PermissionDeniedError"));
}
// Ask for user permission, and dispatch task (or not) when a response
@ -1778,16 +1806,16 @@ nsresult
MediaManager::GetUserMediaDevices(nsPIDOMWindow* aWindow,
const MediaStreamConstraints& aConstraints,
nsIGetUserMediaDevicesSuccessCallback* aOnSuccess,
nsIDOMGetUserMediaErrorCallback* aOnError,
nsIDOMGetUserMediaErrorCallback* aOnFailure,
uint64_t aInnerWindowID)
{
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
NS_ENSURE_TRUE(aOnError, NS_ERROR_NULL_POINTER);
NS_ENSURE_TRUE(aOnFailure, NS_ERROR_NULL_POINTER);
NS_ENSURE_TRUE(aOnSuccess, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIGetUserMediaDevicesSuccessCallback> onSuccess(aOnSuccess);
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> onError(aOnError);
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> onFailure(aOnFailure);
// Check if the preference for using loopback devices is enabled.
nsAdoptingCString loopbackAudioDevice =
@ -1797,7 +1825,7 @@ MediaManager::GetUserMediaDevices(nsPIDOMWindow* aWindow,
MediaManager::GetMessageLoop()->PostTask(FROM_HERE,
new GetUserMediaDevicesTask(
aConstraints, onSuccess.forget(), onError.forget(),
aConstraints, onSuccess.forget(), onFailure.forget(),
(aInnerWindowID ? aInnerWindowID : aWindow->WindowID()),
loopbackAudioDevice, loopbackVideoDevice));
@ -2020,7 +2048,7 @@ MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
MOZ_ASSERT(len);
if (!len) {
// neither audio nor video were selected
task->Denied(NS_LITERAL_STRING("PERMISSION_DENIED"));
task->Denied(NS_LITERAL_STRING("PermissionDeniedError"));
return NS_OK;
}
for (uint32_t i = 0; i < len; i++) {
@ -2047,14 +2075,14 @@ MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
return NS_OK;
} else if (!strcmp(aTopic, "getUserMedia:response:deny")) {
nsString errorMessage(NS_LITERAL_STRING("PERMISSION_DENIED"));
nsString errorMessage(NS_LITERAL_STRING("PermissionDeniedError"));
if (aSubject) {
nsCOMPtr<nsISupportsString> msg(do_QueryInterface(aSubject));
MOZ_ASSERT(msg);
msg->GetData(errorMessage);
if (errorMessage.IsEmpty())
errorMessage.AssignLiteral(MOZ_UTF16("UNKNOWN_ERROR"));
errorMessage.AssignLiteral(MOZ_UTF16("InternalError"));
}
nsString key(aData);

Просмотреть файл

@ -26,6 +26,7 @@
#include "mozilla/StaticPtr.h"
#include "mozilla/dom/MediaStreamBinding.h"
#include "mozilla/dom/MediaStreamTrackBinding.h"
#include "mozilla/dom/MediaStreamError.h"
#include "prlog.h"
#include "DOMMediaStream.h"
@ -268,7 +269,7 @@ class GetUserMediaNotificationEvent: public nsRunnable
already_AddRefed<nsIDOMGetUserMediaErrorCallback> aError)
: mStream(aStream), mOnTracksAvailableCallback(aOnTracksAvailableCallback),
mStatus(aStatus), mIsAudio(aIsAudio), mIsVideo(aIsVideo), mWindowID(aWindowID),
mError(aError) {}
mOnFailure(aError) {}
virtual ~GetUserMediaNotificationEvent()
{
@ -284,7 +285,7 @@ class GetUserMediaNotificationEvent: public nsRunnable
bool mIsAudio;
bool mIsVideo;
uint64_t mWindowID;
nsRefPtr<nsIDOMGetUserMediaErrorCallback> mError;
nsRefPtr<nsIDOMGetUserMediaErrorCallback> mOnFailure;
};
typedef enum {
@ -298,24 +299,24 @@ class MediaManager;
class GetUserMediaTask;
/**
* Send an error back to content. The error is the form a string.
* Do this only on the main thread. The success callback is also passed here
* Send an error back to content.
* Do this only on the main thread. The onSuccess callback is also passed here
* so it can be released correctly.
*/
class ErrorCallbackRunnable : public nsRunnable
{
public:
ErrorCallbackRunnable(
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback>& aSuccess,
nsCOMPtr<nsIDOMGetUserMediaErrorCallback>& aError,
const nsAString& aErrorMsg, uint64_t aWindowID);
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback>& aOnSuccess,
nsCOMPtr<nsIDOMGetUserMediaErrorCallback>& aOnFailure,
MediaMgrError& aError, uint64_t aWindowID);
NS_IMETHOD Run();
private:
~ErrorCallbackRunnable();
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> mSuccess;
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> mError;
const nsString mErrorMsg;
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> mOnSuccess;
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> mOnFailure;
nsRefPtr<MediaMgrError> mError;
uint64_t mWindowID;
nsRefPtr<MediaManager> mManager; // get ref to this when creating the runnable
};
@ -357,7 +358,7 @@ public:
, mListener(aListener)
, mBool(aBool)
, mWindowID(aWindowID)
, mError(aError)
, mOnFailure(aError)
{}
~MediaOperationTask()
@ -373,10 +374,12 @@ public:
mOnTracksAvailableCallback.forget()));
nsString log;
log.AssignASCII(errorLog, strlen(errorLog));
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> success;
NS_DispatchToMainThread(new ErrorCallbackRunnable(success, mError,
log, mWindowID));
log.AssignASCII(errorLog);
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> onSuccess;
nsRefPtr<MediaMgrError> error = new MediaMgrError(
NS_LITERAL_STRING("InternalError"), log);
NS_DispatchToMainThread(new ErrorCallbackRunnable(onSuccess, mOnFailure,
*error, mWindowID));
}
void
@ -428,7 +431,7 @@ public:
mOnTracksAvailableCallback.forget(),
mAudioSource != nullptr,
mVideoSource != nullptr,
mWindowID, mError.forget());
mWindowID, mOnFailure.forget());
// event must always be released on mainthread due to the JS callbacks
// in the TracksAvailableCallback
NS_DispatchToMainThread(event);
@ -490,7 +493,7 @@ private:
nsRefPtr<GetUserMediaCallbackMediaStreamListener> mListener; // threadsafe
bool mBool;
uint64_t mWindowID;
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> mError;
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> mOnFailure;
};
typedef nsTArray<nsRefPtr<GetUserMediaCallbackMediaStreamListener> > StreamListeners;

Просмотреть файл

@ -17,6 +17,7 @@
#include "GetUserMediaRequest.h"
#include "mozilla/dom/PBrowserChild.h"
#include "mozilla/dom/MediaStreamTrackBinding.h"
#include "mozilla/dom/MediaStreamError.h"
#include "nsISupportsPrimitives.h"
#include "nsServiceManagerUtils.h"
#include "nsArrayUtils.h"
@ -224,7 +225,7 @@ MediaPermissionRequest::Cancel()
{
nsString callID;
mRequest->GetCallID(callID);
NotifyPermissionDeny(callID, NS_LITERAL_STRING("Permission Denied"));
NotifyPermissionDeny(callID, NS_LITERAL_STRING("PermissionDeniedError"));
return NS_OK;
}
@ -393,9 +394,17 @@ NS_IMPL_ISUPPORTS(MediaDeviceErrorCallback, nsIDOMGetUserMediaErrorCallback)
// nsIDOMGetUserMediaErrorCallback method
NS_IMETHODIMP
MediaDeviceErrorCallback::OnError(const nsAString &aError)
MediaDeviceErrorCallback::OnError(nsISupports* aError)
{
return NotifyPermissionDeny(mCallID, aError);
MediaStreamError *error = nullptr;
nsresult rv = CallQueryInterface(aError, &error);
if (NS_FAILED(rv)) {
return rv;
}
nsString name;
error->GetName(name);
return NotifyPermissionDeny(mCallID, name);
}
} // namespace anonymous

Просмотреть файл

@ -0,0 +1,81 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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 "MediaStreamError.h"
#include "mozilla/dom/MediaStreamErrorBinding.h"
#include "nsContentUtils.h"
namespace mozilla {
BaseMediaMgrError::BaseMediaMgrError(const nsAString& aName,
const nsAString& aMessage,
const nsAString& aConstraintName)
: mName(aName)
, mMessage(aMessage)
, mConstraintName(aConstraintName)
{
if (mMessage.IsEmpty()) {
if (mName.EqualsLiteral("NotFoundError")) {
mMessage.AssignLiteral("The object can not be found here.");
} else if (mName.EqualsLiteral("PermissionDeniedError")) {
mMessage.AssignLiteral("The user did not grant permission for the operation.");
} else if (mName.EqualsLiteral("SourceUnavailableError")) {
mMessage.AssignLiteral("The source of the MediaStream could not be "
"accessed due to a hardware error (e.g. lock from another process).");
} else if (mName.EqualsLiteral("InternalError")) {
mMessage.AssignLiteral("Internal error.");
}
}
}
NS_IMPL_ISUPPORTS0(MediaMgrError)
namespace dom {
MediaStreamError::MediaStreamError(
nsPIDOMWindow* aParent,
const nsAString& aName,
const nsAString& aMessage,
const nsAString& aConstraintName)
: BaseMediaMgrError(aName, aMessage, aConstraintName)
, mParent(aParent) {}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(MediaStreamError, mParent)
NS_IMPL_CYCLE_COLLECTING_ADDREF(MediaStreamError)
NS_IMPL_CYCLE_COLLECTING_RELEASE(MediaStreamError)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaStreamError)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY(MediaStreamError)
NS_INTERFACE_MAP_END
JSObject*
MediaStreamError::WrapObject(JSContext* aCx)
{
return MediaStreamErrorBinding::Wrap(aCx, this);
}
void
MediaStreamError::GetName(nsAString& aName) const
{
aName = mName;
}
void
MediaStreamError::GetMessage(nsAString& aMessage) const
{
aMessage = mMessage;
}
void
MediaStreamError::GetConstraintName(nsAString& aConstraintName) const
{
aConstraintName = mConstraintName;
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,99 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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_MediaStreamError_h
#define mozilla_dom_MediaStreamError_h
#include "mozilla/Attributes.h"
#include "mozilla/ErrorResult.h"
#include "nsWrapperCache.h"
#include "js/TypeDecls.h"
#include "nsPIDOMWindow.h"
#include "nsRefPtr.h"
#if defined(XP_WIN) && defined(GetMessage)
#undef GetMessage
#endif
namespace mozilla {
namespace dom {
#define MOZILLA_DOM_MEDIASTREAMERROR_IMPLEMENTATION_IID \
{ 0x95fa29aa, 0x0cc2, 0x4698, \
{ 0x9d, 0xa9, 0xf2, 0xeb, 0x03, 0x91, 0x0b, 0xd1 } }
class MediaStreamError;
}
class BaseMediaMgrError
{
friend class dom::MediaStreamError;
protected:
BaseMediaMgrError(const nsAString& aName,
const nsAString& aMessage,
const nsAString& aConstraintName);
const nsString mName;
nsString mMessage;
const nsString mConstraintName;
};
class MediaMgrError MOZ_FINAL : public nsISupports,
public BaseMediaMgrError
{
public:
MediaMgrError(const nsAString& aName,
const nsAString& aMessage = EmptyString(),
const nsAString& aConstraintName = EmptyString())
: BaseMediaMgrError(aName, aMessage, aConstraintName) {}
NS_DECL_THREADSAFE_ISUPPORTS
private:
~MediaMgrError() {}
};
namespace dom {
class MediaStreamError MOZ_FINAL : public nsISupports,
public BaseMediaMgrError,
public nsWrapperCache
{
public:
MediaStreamError(nsPIDOMWindow* aParent,
const nsAString& aName,
const nsAString& aMessage = EmptyString(),
const nsAString& aConstraintName = EmptyString());
MediaStreamError(nsPIDOMWindow* aParent,
const BaseMediaMgrError& aOther)
: BaseMediaMgrError(aOther.mName, aOther.mMessage, aOther.mConstraintName)
, mParent(aParent) {}
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MediaStreamError)
NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_DOM_MEDIASTREAMERROR_IMPLEMENTATION_IID)
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
nsPIDOMWindow* GetParentObject() const
{
return mParent;
}
void GetName(nsAString& aName) const;
void GetMessage(nsAString& aMessage) const;
void GetConstraintName(nsAString& aConstraintName) const;
private:
virtual ~MediaStreamError() {}
nsRefPtr<nsPIDOMWindow> mParent;
};
NS_DEFINE_STATIC_IID_ACCESSOR(MediaStreamError,
MOZILLA_DOM_MEDIASTREAMERROR_IMPLEMENTATION_IID)
} // namespace dom
} // namespace mozilla
#endif

Просмотреть файл

@ -70,6 +70,11 @@ public:
return mInfo.HasAudio();
}
// We can't compute a proper start time since we won't necessarily
// have the first frame of the resource available. This does the same
// as chrome/blink and assumes that we always start at t=0.
virtual int64_t ComputeStartTime(const VideoData* aVideo, const AudioData* aAudio) MOZ_OVERRIDE { return 0; }
bool IsMediaSeekable() { return true; }
nsresult ReadMetadata(MediaInfo* aInfo, MetadataTags** aTags) MOZ_OVERRIDE;

Просмотреть файл

@ -143,6 +143,8 @@ EXPORTS.mozilla.dom += [
'AudioTrack.h',
'AudioTrackList.h',
'GetUserMediaRequest.h',
'MediaDevices.h',
'MediaStreamError.h',
'MediaStreamTrack.h',
'TextTrack.h',
'TextTrackCue.h',
@ -177,10 +179,12 @@ UNIFIED_SOURCES += [
'MediaDecoderReader.cpp',
'MediaDecoderStateMachine.cpp',
'MediaDecoderStateMachineScheduler.cpp',
'MediaDevices.cpp',
'MediaManager.cpp',
'MediaRecorder.cpp',
'MediaResource.cpp',
'MediaShutdownManager.cpp',
'MediaStreamError.cpp',
'MediaStreamGraph.cpp',
'MediaStreamTrack.cpp',
'MediaTaskQueue.cpp',

Просмотреть файл

@ -34,5 +34,5 @@ interface nsIDOMGetUserMediaSuccessCallback : nsISupports
[scriptable, function, uuid(2614bbcf-85cc-43e5-8740-964f52bdc7ca)]
interface nsIDOMGetUserMediaErrorCallback : nsISupports
{
void onError(in DOMString error);
void onError(in nsISupports error);
};

Просмотреть файл

@ -14,19 +14,19 @@ var common_tests = [
{ message: "unknown required constraint on video fails",
constraints: { video: { somethingUnknown:0, require:["somethingUnknown"] },
fake: true },
error: "NO_DEVICES_FOUND" },
error: "NotFoundError" },
{ message: "unknown required constraint on audio fails",
constraints: { audio: { somethingUnknown:0, require:["somethingUnknown"] },
fake: true },
error: "NO_DEVICES_FOUND" },
error: "NotFoundError" },
{ message: "video overconstrained by facingMode fails",
constraints: { video: { facingMode:'left', require:["facingMode"] },
fake: true },
error: "NO_DEVICES_FOUND" },
error: "NotFoundError" },
{ message: "audio overconstrained by facingMode fails",
constraints: { audio: { facingMode:'left', require:["facingMode"] },
fake: true },
error: "NO_DEVICES_FOUND" },
error: "NotFoundError" },
{ message: "Success-path: optional video facingMode + audio ignoring facingMode",
constraints: { fake: true,
audio: { facingMode:'left',
@ -48,29 +48,27 @@ var common_tests = [
/**
* Starts the test run by running through each constraint
* test by verifying that the right callback and error message is fired.
* test by verifying that the right resolution and rejection is fired.
*/
function testConstraints(tests) {
var i = 0;
next();
function testgum(p, test) {
return p.then(function() {
return navigator.mediaDevices.getUserMedia(test.constraints);
})
.then(function() {
is(null, test.error, test.message);
}, function(reason) {
is(reason.name, test.error, test.message + ": " + reason.message);
});
}
function Success() {
ok(!tests[i].error, tests[i].message);
i++;
next();
}
function Failure(err) {
ok(tests[i].error? (err === tests[i].error) : false,
tests[i].message + " (err=" + err + ")");
i++;
next();
}
function next() {
if (i < tests.length) {
navigator.mozGetUserMedia(tests[i].constraints, Success, Failure);
} else {
SimpleTest.finish();
}
}
};
var p = new Promise(function(resolve) { resolve(); });
tests.forEach(function(test) {
p = testgum(p, test);
});
p.catch(function(reason) {
ok(false, "Unexpected failure: " + reason.message);
})
.then(SimpleTest.finish);
}

Просмотреть файл

@ -26,7 +26,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=882145
var mobile_tests = [
{ message: "legacy facingMode overconstrains video (mobile)",
constraints: { video: { mandatory: { facingMode:'left' } }, fake: true },
error: "NO_DEVICES_FOUND" },
error: "NotFoundError" },
];
runTest(function () {

Просмотреть файл

@ -26,7 +26,7 @@ function theTest() {
config.peerIdentity = 'user@example.com';
}
info('getting media with constraints: ' + JSON.stringify(config));
navigator.mozGetUserMedia(config, function(stream) {
navigator.mediaDevices.getUserMedia(config).then(function(stream) {
var oneDone = false;
function checkDone() {
if (oneDone) {
@ -38,7 +38,8 @@ function theTest() {
var cancelVideoCheck = videoIsBlack(withConstraint, stream, checkDone);
setTimeout(cancelAudioCheck, 3*60*1000);
setTimeout(cancelVideoCheck, 3*60*1000);
}, function(e) {
})
.catch(function(e) {
ok(false, 'gUM error: ' + e);
});
};

Просмотреть файл

@ -37,23 +37,23 @@
var track = stream.getVideoTracks()[0];
var sender = test.pcLocal._pc.getSenders().find(isSenderOfTrack, track);
ok(sender, "track has a sender");
navigator.mozGetUserMedia({video:true, fake: true}, function(newStream) {
navigator.mediaDevices.getUserMedia({video:true, fake: true})
.then(function(newStream) {
var newtrack = newStream.getVideoTracks()[0];
sender.replaceTrack(newtrack,
function() {
ok(true, "replaceTrack success callback is called");
is(sender.track, newtrack, "sender.track has been replaced");
test.next();
},
function(err) {
ok(false, "replaceTrack failed with error = " + err);
test.next();
});
},
function(err) {
ok(false, "mozGetUserMedia failed. error = " + err);
test.next();
});
return new Promise(function(resolve, reject) {
sender.replaceTrack(newtrack, function() {
resolve(newtrack);
}, reject);
});
})
.then(function(newtrack) {
ok(true, "replaceTrack success callback is called");
is(sender.track, newtrack, "sender.track has been replaced");
})
.catch(function(reason) {
ok(false, "unexpected error = " + reason.message);
})
.then(test.next.bind(test));
}
]]);
test.chain.append(flowtest);

Просмотреть файл

@ -11,6 +11,7 @@
#include "mozilla/dom/SpeechRecognitionBinding.h"
#include "mozilla/dom/MediaStreamTrackBinding.h"
#include "mozilla/dom/MediaStreamError.h"
#include "mozilla/MediaManager.h"
#include "mozilla/Services.h"
@ -23,6 +24,11 @@
#include <algorithm>
// Undo the windows.h damage
#if defined(XP_WIN) && defined(GetMessage)
#undef GetMessage
#endif
namespace mozilla {
namespace dom {
@ -945,19 +951,26 @@ SpeechRecognition::GetUserMediaSuccessCallback::OnSuccess(nsISupports* aStream)
NS_IMPL_ISUPPORTS(SpeechRecognition::GetUserMediaErrorCallback, nsIDOMGetUserMediaErrorCallback)
NS_IMETHODIMP
SpeechRecognition::GetUserMediaErrorCallback::OnError(const nsAString& aError)
SpeechRecognition::GetUserMediaErrorCallback::OnError(nsISupports* aError)
{
nsRefPtr<MediaStreamError> error = do_QueryObject(aError);
if (!error) {
return NS_OK;
}
SpeechRecognitionErrorCode errorCode;
if (aError.EqualsLiteral("PERMISSION_DENIED")) {
nsString name;
error->GetName(name);
if (name.EqualsLiteral("PERMISSION_DENIED")) {
errorCode = SpeechRecognitionErrorCode::Not_allowed;
} else {
errorCode = SpeechRecognitionErrorCode::Audio_capture;
}
nsString message;
error->GetMessage(message);
mRecognition->DispatchError(SpeechRecognition::EVENT_AUDIO_ERROR, errorCode,
aError);
message);
return NS_OK;
}

Просмотреть файл

@ -12,6 +12,7 @@
#include "mozilla/dom/OwningNonNull.h"
#include "mozilla/dom/PromiseBinding.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/MediaStreamError.h"
#include "mozilla/CycleCollectedJSRuntime.h"
#include "mozilla/Preferences.h"
#include "PromiseCallback.h"
@ -354,6 +355,11 @@ Promise::MaybeReject(JSContext* aCx,
MaybeRejectInternal(aCx, aValue);
}
void
Promise::MaybeReject(const nsRefPtr<MediaStreamError>& aArg) {
MaybeSomething(aArg, &Promise::MaybeReject);
}
void
Promise::PerformMicroTaskCheckpoint()
{

Просмотреть файл

@ -29,6 +29,7 @@ namespace dom {
class AnyCallback;
class DOMError;
class MediaStreamError;
class PromiseCallback;
class PromiseInit;
class PromiseNativeHandler;
@ -99,6 +100,9 @@ public:
MOZ_ASSERT(NS_FAILED(aArg));
MaybeSomething(aArg, &Promise::MaybeReject);
}
void MaybeReject(const nsRefPtr<MediaStreamError>& aArg);
// DO NOT USE MaybeRejectBrokenly with in new code. Promises should be
// rejected with Error instances.
// Note: MaybeRejectBrokenly is a template so we can use it with DOMError

Просмотреть файл

@ -1101,7 +1101,7 @@ QuotaManager::DecreaseUsageForOrigin(PersistenceType aPersistenceType,
const nsACString& aOrigin,
int64_t aSize)
{
AssertIsOnIOThread();
MOZ_ASSERT(!NS_IsMainThread());
MutexAutoLock lock(mQuotaMutex);

Просмотреть файл

@ -81,6 +81,34 @@ SVGCircleElement::GetLengthInfo()
//----------------------------------------------------------------------
// nsSVGPathGeometryElement methods
bool
SVGCircleElement::GetGeometryBounds(Rect* aBounds, Float aStrokeWidth,
const Matrix& aTransform)
{
float x, y, r;
GetAnimatedLengthValues(&x, &y, &r, nullptr);
if (r <= 0.f) {
// Rendering of the element is disabled
aBounds->MoveTo(x, y);
aBounds->SetEmpty();
return true;
}
if (aTransform.IsRectilinear()) {
// Optimize the case where we can treat the circle as a rectangle and
// still get tight bounds.
if (aStrokeWidth > 0.f) {
r += aStrokeWidth / 2.f;
}
Rect rect(x - r, y - r, 2 * r, 2 * r);
*aBounds = aTransform.TransformBounds(rect);
return true;
}
return false;
}
TemporaryRef<Path>
SVGCircleElement::BuildPath(PathBuilder* aBuilder)
{

Просмотреть файл

@ -30,6 +30,8 @@ public:
virtual bool HasValidDimensions() const MOZ_OVERRIDE;
// nsSVGPathGeometryElement methods:
virtual bool GetGeometryBounds(Rect* aBounds, Float aStrokeWidth,
const Matrix& aTransform) MOZ_OVERRIDE;
virtual TemporaryRef<Path> BuildPath(PathBuilder* aBuilder) MOZ_OVERRIDE;
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;

Просмотреть файл

@ -92,6 +92,35 @@ SVGEllipseElement::GetLengthInfo()
//----------------------------------------------------------------------
// nsSVGPathGeometryElement methods
bool
SVGEllipseElement::GetGeometryBounds(Rect* aBounds, Float aStrokeWidth,
const Matrix& aTransform)
{
float x, y, rx, ry;
GetAnimatedLengthValues(&x, &y, &rx, &ry, nullptr);
if (rx <= 0.f || ry <= 0.f) {
// Rendering of the element is disabled
aBounds->MoveTo(x, y);
aBounds->SetEmpty();
return true;
}
if (aTransform.IsRectilinear()) {
// Optimize the case where we can treat the ellipse as a rectangle and
// still get tight bounds.
if (aStrokeWidth > 0.f) {
rx += aStrokeWidth / 2.f;
ry += aStrokeWidth / 2.f;
}
Rect rect(x - rx, y - ry, 2 * rx, 2 * ry);
*aBounds = aTransform.TransformBounds(rect);
return true;
}
return false;
}
TemporaryRef<Path>
SVGEllipseElement::BuildPath(PathBuilder* aBuilder)
{

Просмотреть файл

@ -30,6 +30,8 @@ public:
virtual bool HasValidDimensions() const MOZ_OVERRIDE;
// nsSVGPathGeometryElement methods:
virtual bool GetGeometryBounds(Rect* aBounds, Float aStrokeWidth,
const Matrix& aTransform) MOZ_OVERRIDE;
virtual TemporaryRef<Path> BuildPath(PathBuilder* aBuilder) MOZ_OVERRIDE;
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;

Просмотреть файл

@ -70,6 +70,12 @@ public:
virtual bool IsMarkable();
virtual void GetMarkPoints(nsTArray<nsSVGMark> *aMarks);
/**
* A method that can be faster than using a Moz2D Path and calling GetBounds/
* GetStrokedBounds on it. It also helps us avoid rounding error for simple
* shapes and simple transforms where the Moz2D Path backends can fail to
* produce the clean integer bounds that content authors expect in some cases.
*/
virtual bool GetGeometryBounds(Rect* aBounds, Float aStrokeWidth,
const Matrix& aTransform) {
return false;

Просмотреть файл

@ -635,6 +635,8 @@ var interfaceNamesInGlobalScope =
"LocalMediaStream",
// IMPORTANT: Do not change this list without review from a DOM peer!
"Location",
// IMPORTANT: Do not change this list without review from a DOM peer!
"MediaDevices",
// IMPORTANT: Do not change this list without review from a DOM peer!
"MediaElementAudioSourceNode",
// IMPORTANT: Do not change this list without review from a DOM peer!

Просмотреть файл

@ -0,0 +1,23 @@
/* -*- 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/.
*
* The origin of this IDL file is
* http://dev.w3.org/2011/webrtc/editor/getusermedia.html
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
[Func="Navigator::HasUserMediaSupport"]
interface MediaDevices : EventTarget {
// attribute EventHandler ondevicechange;
//
// void enumerateDevices (MediaDeviceInfoCallback resultCallback);
//
// static Dictionary getSupportedConstraints (DOMString kind);
[Throws, Func="Navigator::HasUserMediaSupport"]
Promise<MediaStream> getUserMedia(optional MediaStreamConstraints constraints);
};

Просмотреть файл

@ -0,0 +1,21 @@
/* -*- 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/.
*
* The origin of this IDL file is
* http://w3c.github.io/mediacapture-main/getusermedia.html#idl-def-MediaStreamError
*/
// The future of MediaStreamError is uncertain.
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=26776
// TODO: This is an 'exception', not an interface, by virtue of needing to be
// passed as a promise rejection-reason. Revisit if DOMException grows a customArg
[ExceptionClass, NoInterfaceObject]
interface MediaStreamError {
readonly attribute DOMString name;
readonly attribute DOMString? message;
readonly attribute DOMString? constraintName;
};

Просмотреть файл

@ -354,9 +354,13 @@ partial interface Navigator {
#ifdef MOZ_MEDIA_NAVIGATOR
callback NavigatorUserMediaSuccessCallback = void (MediaStream stream);
callback NavigatorUserMediaErrorCallback = void (DOMString error);
callback NavigatorUserMediaErrorCallback = void (MediaStreamError error);
partial interface Navigator {
[Throws, Func="Navigator::HasUserMediaSupport"]
readonly attribute MediaDevices mediaDevices;
// Deprecated. Use mediaDevices.getUserMedia instead.
[Throws, Func="Navigator::HasUserMediaSupport"]
void mozGetUserMedia(MediaStreamConstraints constraints,
NavigatorUserMediaSuccessCallback successCallback,

Просмотреть файл

@ -255,6 +255,7 @@ WEBIDL_FILES = [
'ListBoxObject.webidl',
'LocalMediaStream.webidl',
'Location.webidl',
'MediaDevices.webidl',
'MediaElementAudioSourceNode.webidl',
'MediaError.webidl',
'MediaList.webidl',
@ -264,6 +265,7 @@ WEBIDL_FILES = [
'MediaStream.webidl',
'MediaStreamAudioDestinationNode.webidl',
'MediaStreamAudioSourceNode.webidl',
'MediaStreamError.webidl',
'MediaStreamTrack.webidl',
'MediaTrackConstraintSet.webidl',
'MenuBoxObject.webidl',

Просмотреть файл

@ -45,6 +45,52 @@ class AutoRestoreTransform
Matrix mOldTransform;
};
class AutoPopClips
{
public:
explicit AutoPopClips(DrawTarget *aTarget)
: mDrawTarget(aTarget)
, mPushCount(0)
{
MOZ_ASSERT(mDrawTarget);
}
~AutoPopClips()
{
PopAll();
}
void PushClip(const Path *aPath)
{
mDrawTarget->PushClip(aPath);
++mPushCount;
}
void PushClipRect(const Rect &aRect)
{
mDrawTarget->PushClipRect(aRect);
++mPushCount;
}
void PopClip()
{
MOZ_ASSERT(mPushCount > 0);
mDrawTarget->PopClip();
--mPushCount;
}
void PopAll()
{
while (mPushCount-- > 0) {
mDrawTarget->PopClip();
}
}
private:
RefPtr<DrawTarget> mDrawTarget;
int32_t mPushCount;
};
} // namespace gfx
} // namespace mozilla

Просмотреть файл

@ -7,6 +7,7 @@
#include <math.h>
#include "DrawTargetCG.h"
#include "Logging.h"
#include "PathHelpers.h"
namespace mozilla {
namespace gfx {
@ -68,6 +69,10 @@ void
PathBuilderCG::Arc(const Point &aOrigin, Float aRadius, Float aStartAngle,
Float aEndAngle, bool aAntiClockwise)
{
// Disabled for now due to a CG bug when using CGPathAddArc with stroke
// dashing and rotation transforms that are multiples of 90 degrees. See:
// https://bugzilla.mozilla.org/show_bug.cgi?id=949661#c8
#if 0
// Core Graphic's initial coordinate system is y-axis up, whereas Moz2D's is
// y-axis down. Core Graphics therefore considers "clockwise" to mean "sweep
// in the direction of decreasing angle" whereas Moz2D considers it to mean
@ -82,6 +87,9 @@ PathBuilderCG::Arc(const Point &aOrigin, Float aRadius, Float aStartAngle,
aStartAngle,
aEndAngle,
aAntiClockwise);
#endif
ArcToBezier(this, aOrigin, Size(aRadius, aRadius), aStartAngle, aEndAngle,
aAntiClockwise);
}
Point

Просмотреть файл

@ -14,7 +14,6 @@ TransGaming Inc.
Adobe Systems Inc.
Autodesk, Inc.
BlackBerry Limited
Borbitsoft
Cable Television Laboratories, Inc.
Cloud Party, Inc.
Intel Corporation
@ -22,10 +21,12 @@ Mozilla Corporation
Turbulenz
Klarälvdalens Datakonsult AB
Microsoft Open Technologies, Inc.
NVIDIA Corporation
Jacek Caban
Mark Callow
Ginn Chen
Tibor den Ouden
James Hauxwell
Sam Hocevar
Pierre Leveille

Просмотреть файл

@ -49,9 +49,6 @@ Adobe Systems Inc.
Autodesk, Inc.
Ranger Harke
Borbitsoft
Tibor den Ouden
Cloud Party, Inc.
Conor Dickinson
@ -82,7 +79,11 @@ Ulrik Persson (ddefrostt)
Mark Banner (standard8mbp)
David Kilzer
Jacek Caban
Tibor den Ouden
Microsoft Open Technologies, Inc.
Cooper Partin
Austin Kinross
NVIDIA Corporation
Olli Etuaho

Просмотреть файл

@ -246,6 +246,12 @@ typedef struct
int EXT_frag_depth;
int EXT_shader_texture_lod;
// Set to 1 to enable replacing GL_EXT_draw_buffers #extension directives
// with GL_NV_draw_buffers in ESSL output. This flag can be used to emulate
// EXT_draw_buffers by using it in combination with GLES3.0 glDrawBuffers
// function. This applies to Tegra K1 devices.
int NV_draw_buffers;
// Set to 1 if highp precision is supported in the fragment language.
// Default is 0.
int FragmentPrecisionHigh;

Просмотреть файл

@ -52,6 +52,21 @@ struct COMPILER_EXPORT ShaderVariable
unsigned int elementCount() const { return std::max(1u, arraySize); }
bool isStruct() const { return !fields.empty(); }
// All of the shader's variables are described using nested data
// structures. This is needed in order to disambiguate similar looking
// types, such as two structs containing the same fields, but in
// different orders. "findInfoByMappedName" provides an easy query for
// users to dive into the data structure and fetch the unique variable
// instance corresponding to a dereferencing chain of the top-level
// variable.
// Given a mapped name like 'a[0].b.c[0]', return the ShaderVariable
// that defines 'c' in |leafVar|, and the original name 'A[0].B.C[0]'
// in |originalName|, based on the assumption that |this| defines 'a'.
// If no match is found, return false.
bool findInfoByMappedName(const std::string &mappedFullName,
const ShaderVariable **leafVar,
std::string* originalFullName) const;
GLenum type;
GLenum precision;
std::string name;
@ -60,6 +75,16 @@ struct COMPILER_EXPORT ShaderVariable
bool staticUse;
std::vector<ShaderVariable> fields;
std::string structName;
protected:
bool isSameVariableAtLinkTime(const ShaderVariable &other,
bool matchPrecision) const;
bool operator==(const ShaderVariable &other) const;
bool operator!=(const ShaderVariable &other) const
{
return !operator==(other);
}
};
struct COMPILER_EXPORT Uniform : public ShaderVariable
@ -68,6 +93,16 @@ struct COMPILER_EXPORT Uniform : public ShaderVariable
~Uniform();
Uniform(const Uniform &other);
Uniform &operator=(const Uniform &other);
bool operator==(const Uniform &other) const;
bool operator!=(const Uniform &other) const
{
return !operator==(other);
}
// Decide whether two uniforms are the same at shader link time,
// assuming one from vertex shader and the other from fragment shader.
// See GLSL ES Spec 3.00.3, sec 4.3.5.
bool isSameUniformAtLinkTime(const Uniform &other) const;
};
struct COMPILER_EXPORT Attribute : public ShaderVariable
@ -76,6 +111,11 @@ struct COMPILER_EXPORT Attribute : public ShaderVariable
~Attribute();
Attribute(const Attribute &other);
Attribute &operator=(const Attribute &other);
bool operator==(const Attribute &other) const;
bool operator!=(const Attribute &other) const
{
return !operator==(other);
}
int location;
};
@ -86,6 +126,18 @@ struct COMPILER_EXPORT InterfaceBlockField : public ShaderVariable
~InterfaceBlockField();
InterfaceBlockField(const InterfaceBlockField &other);
InterfaceBlockField &operator=(const InterfaceBlockField &other);
bool operator==(const InterfaceBlockField &other) const;
bool operator!=(const InterfaceBlockField &other) const
{
return !operator==(other);
}
// Decide whether two InterfaceBlock fields are the same at shader
// link time, assuming one from vertex shader and the other from
// fragment shader.
// See GLSL ES Spec 3.00.3, sec 4.3.7.
bool isSameInterfaceBlockFieldAtLinkTime(
const InterfaceBlockField &other) const;
bool isRowMajorLayout;
};
@ -94,8 +146,18 @@ struct COMPILER_EXPORT Varying : public ShaderVariable
{
Varying();
~Varying();
Varying(const Varying &other);
Varying(const Varying &otherg);
Varying &operator=(const Varying &other);
bool operator==(const Varying &other) const;
bool operator!=(const Varying &other) const
{
return !operator==(other);
}
// Decide whether two varyings are the same at shader link time,
// assuming one from vertex shader and the other from fragment shader.
// See GLSL ES Spec 3.00.3, sec 4.3.9.
bool isSameVaryingAtLinkTime(const Varying &other) const;
InterpolationType interpolation;
bool isInvariant;

Просмотреть файл

@ -1,3 +1,3 @@
#define ANGLE_COMMIT_HASH "7a2ba5a15abc"
#define ANGLE_COMMIT_HASH "f0cacb827771"
#define ANGLE_COMMIT_HASH_SIZE 12
#define ANGLE_COMMIT_DATE "2014-10-25 15:19:56 -0400"
#define ANGLE_COMMIT_DATE "2014-10-28 23:00:12 -0400"

Просмотреть файл

@ -6,6 +6,7 @@
#include "common/angleutils.h"
#include <stdio.h>
#include <vector>
std::string FormatString(const char *fmt, va_list vararg)

Просмотреть файл

@ -360,7 +360,8 @@ void TCompiler::setResourceString()
<< ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors
<< ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors
<< ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset
<< ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset;
<< ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset
<< ":NV_draw_buffers:" << compileResources.NV_draw_buffers;
builtInResourcesString = strstream.str();
}

Просмотреть файл

@ -201,6 +201,8 @@ void ShInitBuiltInResources(ShBuiltInResources* resources)
resources->EXT_frag_depth = 0;
resources->EXT_shader_texture_lod = 0;
resources->NV_draw_buffers = 0;
// Disable highp precision in fragment shader by default.
resources->FragmentPrecisionHigh = 0;

Просмотреть файл

@ -9,6 +9,8 @@
#include <GLSLANG/ShaderLang.h>
#include "compiler/translator/compilerdebug.h"
namespace sh
{
@ -53,6 +55,126 @@ ShaderVariable &ShaderVariable::operator=(const ShaderVariable &other)
return *this;
}
bool ShaderVariable::operator==(const ShaderVariable &other) const
{
if (type != other.type ||
precision != other.precision ||
name != other.name ||
mappedName != other.mappedName ||
arraySize != other.arraySize ||
staticUse != other.staticUse ||
fields.size() != other.fields.size() ||
structName != other.structName)
{
return false;
}
for (size_t ii = 0; ii < fields.size(); ++ii)
{
if (fields[ii] != other.fields[ii])
return false;
}
return true;
}
bool ShaderVariable::findInfoByMappedName(
const std::string &mappedFullName,
const ShaderVariable **leafVar, std::string *originalFullName) const
{
ASSERT(leafVar && originalFullName);
// There are three cases:
// 1) the top variable is of struct type;
// 2) the top variable is an array;
// 3) otherwise.
size_t pos = mappedFullName.find_first_of(".[");
std::string topName;
if (pos == std::string::npos)
{
// Case 3.
if (mappedFullName != this->mappedName)
return false;
*originalFullName = this->name;
*leafVar = this;
return true;
}
else
{
std::string topName = mappedFullName.substr(0, pos);
if (topName != this->mappedName)
return false;
std::string originalName = this->name;
std::string remaining;
if (mappedFullName[pos] == '[')
{
// Case 2.
size_t closePos = mappedFullName.find_first_of(']');
if (closePos < pos || closePos == std::string::npos)
return false;
// Append '[index]'.
originalName += mappedFullName.substr(pos, closePos - pos + 1);
if (closePos + 1 == mappedFullName.size())
{
*originalFullName = originalName;
*leafVar = this;
return true;
}
else
{
// In the form of 'a[0].b', so after ']', '.' is expected.
if (mappedFullName[closePos + 1] != '.')
return false;
remaining = mappedFullName.substr(closePos + 2); // Skip "]."
}
}
else
{
// Case 1.
remaining = mappedFullName.substr(pos + 1); // Skip "."
}
for (size_t ii = 0; ii < this->fields.size(); ++ii)
{
const ShaderVariable *fieldVar = NULL;
std::string originalFieldName;
bool found = fields[ii].findInfoByMappedName(
remaining, &fieldVar, &originalFieldName);
if (found)
{
*originalFullName = originalName + "." + originalFieldName;
*leafVar = fieldVar;
return true;
}
}
return false;
}
}
bool ShaderVariable::isSameVariableAtLinkTime(
const ShaderVariable &other, bool matchPrecision) const
{
if (type != other.type)
return false;
if (matchPrecision && precision != other.precision)
return false;
if (name != other.name)
return false;
ASSERT(mappedName == other.mappedName);
if (arraySize != other.arraySize)
return false;
if (fields.size() != other.fields.size())
return false;
for (size_t ii = 0; ii < fields.size(); ++ii)
{
if (!fields[ii].isSameVariableAtLinkTime(other.fields[ii],
matchPrecision))
{
return false;
}
}
if (structName != other.structName)
return false;
return true;
}
Uniform::Uniform()
{}
@ -69,6 +191,16 @@ Uniform &Uniform::operator=(const Uniform &other)
return *this;
}
bool Uniform::operator==(const Uniform &other) const
{
return ShaderVariable::operator==(other);
}
bool Uniform::isSameUniformAtLinkTime(const Uniform &other) const
{
return ShaderVariable::isSameVariableAtLinkTime(other, true);
}
Attribute::Attribute()
: location(-1)
{}
@ -88,6 +220,12 @@ Attribute &Attribute::operator=(const Attribute &other)
return *this;
}
bool Attribute::operator==(const Attribute &other) const
{
return (ShaderVariable::operator==(other) &&
location == other.location);
}
InterfaceBlockField::InterfaceBlockField()
: isRowMajorLayout(false)
{}
@ -107,6 +245,19 @@ InterfaceBlockField &InterfaceBlockField::operator=(const InterfaceBlockField &o
return *this;
}
bool InterfaceBlockField::operator==(const InterfaceBlockField &other) const
{
return (ShaderVariable::operator==(other) &&
isRowMajorLayout == other.isRowMajorLayout);
}
bool InterfaceBlockField::isSameInterfaceBlockFieldAtLinkTime(
const InterfaceBlockField &other) const
{
return (ShaderVariable::isSameVariableAtLinkTime(other, true) &&
isRowMajorLayout == other.isRowMajorLayout);
}
Varying::Varying()
: interpolation(INTERPOLATION_SMOOTH),
isInvariant(false)
@ -129,6 +280,20 @@ Varying &Varying::operator=(const Varying &other)
return *this;
}
bool Varying::operator==(const Varying &other) const
{
return (ShaderVariable::operator==(other) &&
interpolation == other.interpolation &&
isInvariant == other.isInvariant);
}
bool Varying::isSameVaryingAtLinkTime(const Varying &other) const
{
return (ShaderVariable::isSameVariableAtLinkTime(other, false) &&
interpolation == other.interpolation &&
isInvariant == other.isInvariant);
}
InterfaceBlock::InterfaceBlock()
: arraySize(0),
layout(BLOCKLAYOUT_PACKED),

Просмотреть файл

@ -37,8 +37,13 @@ void TranslatorESSL::writeExtensionBehavior() {
for (TExtensionBehavior::const_iterator iter = extensionBehavior.begin();
iter != extensionBehavior.end(); ++iter) {
if (iter->second != EBhUndefined) {
sink << "#extension " << iter->first << " : "
<< getBehaviorString(iter->second) << "\n";
if (getResources().NV_draw_buffers && iter->first == "GL_EXT_draw_buffers") {
sink << "#extension GL_NV_draw_buffers : "
<< getBehaviorString(iter->second) << "\n";
} else {
sink << "#extension " << iter->first << " : "
<< getBehaviorString(iter->second) << "\n";
}
}
}
}

Просмотреть файл

@ -91,13 +91,13 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere
bindRenderbuffer(0);
bindGenericUniformBuffer(0);
for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++)
for (unsigned int i = 0; i < mCaps.maxCombinedUniformBlocks; i++)
{
bindIndexedUniformBuffer(0, i, 0, -1);
}
bindGenericTransformFeedbackBuffer(0);
for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
for (unsigned int i = 0; i < mCaps.maxTransformFeedbackSeparateAttributes; i++)
{
bindIndexedTransformFeedbackBuffer(0, i, 0, -1);
}
@ -119,8 +119,6 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere
mResetStatus = GL_NO_ERROR;
mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT);
mRobustAccess = robustAccess;
mState.setContext(this);
}
Context::~Context()
@ -640,33 +638,44 @@ void Context::useProgram(GLuint program)
}
}
void Context::linkProgram(GLuint program)
Error Context::linkProgram(GLuint program)
{
Program *programObject = mResourceManager->getProgram(program);
bool linked = programObject->link(getCaps());
Error error = programObject->link(getCaps());
if (error.isError())
{
return error;
}
// if the current program was relinked successfully we
// need to install the new executables
if (linked && program == mState.getCurrentProgramId())
if (programObject->isLinked() && program == mState.getCurrentProgramId())
{
mState.setCurrentProgramBinary(programObject->getProgramBinary());
}
return Error(GL_NO_ERROR);
}
void Context::setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length)
Error Context::setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length)
{
Program *programObject = mResourceManager->getProgram(program);
bool loaded = programObject->setProgramBinary(binaryFormat, binary, length);
Error error = programObject->setProgramBinary(binaryFormat, binary, length);
if (error.isError())
{
return error;
}
// if the current program was reloaded successfully we
// need to install the new executables
if (loaded && program == mState.getCurrentProgramId())
if (programObject->isLinked() && program == mState.getCurrentProgramId())
{
mState.setCurrentProgramBinary(programObject->getProgramBinary());
}
return Error(GL_NO_ERROR);
}
void Context::bindTransformFeedback(GLuint transformFeedback)
@ -1398,10 +1407,8 @@ Error Context::applyState(GLenum drawMode)
// Applies the shaders and shader constants to the Direct3D 9 device
Error Context::applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive)
{
const VertexAttribute *vertexAttributes = mState.getVertexArray()->getVertexAttributes();
VertexFormat inputLayout[MAX_VERTEX_ATTRIBS];
VertexFormat::GetInputLayout(inputLayout, programBinary, vertexAttributes, mState.getVertexAttribCurrentValues());
VertexFormat::GetInputLayout(inputLayout, programBinary, mState);
const Framebuffer *fbo = mState.getDrawFramebuffer();
@ -1584,14 +1591,7 @@ bool Context::applyTransformFeedbackBuffers()
TransformFeedback *curTransformFeedback = mState.getCurrentTransformFeedback();
if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
{
Buffer *transformFeedbackBuffers[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
GLintptr transformFeedbackOffsets[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
{
transformFeedbackBuffers[i] = mState.getIndexedTransformFeedbackBuffer(i);
transformFeedbackOffsets[i] = mState.getIndexedTransformFeedbackBufferOffset(i);
}
mRenderer->applyTransformFeedbackBuffers(transformFeedbackBuffers, transformFeedbackOffsets);
mRenderer->applyTransformFeedbackBuffers(mState);
return true;
}
else
@ -1602,7 +1602,7 @@ bool Context::applyTransformFeedbackBuffers()
void Context::markTransformFeedbackUsage()
{
for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
for (size_t i = 0; i < mCaps.maxTransformFeedbackSeparateAttributes; i++)
{
Buffer *buffer = mState.getIndexedTransformFeedbackBuffer(i);
if (buffer)
@ -1771,7 +1771,7 @@ Error Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei insta
return error;
}
error = mRenderer->applyVertexBuffer(programBinary, mState.getVertexArray()->getVertexAttributes(), mState.getVertexAttribCurrentValues(), first, count, instances);
error = mRenderer->applyVertexBuffer(mState, first, count, instances);
if (error.isError())
{
return error;
@ -1856,9 +1856,7 @@ Error Context::drawElements(GLenum mode, GLsizei count, GLenum type,
}
GLsizei vertexCount = indexInfo.indexRange.length() + 1;
error = mRenderer->applyVertexBuffer(programBinary, vao->getVertexAttributes(),
mState.getVertexAttribCurrentValues(),
indexInfo.indexRange.start, vertexCount, instances);
error = mRenderer->applyVertexBuffer(mState, indexInfo.indexRange.start, vertexCount, instances);
if (error.isError())
{
return error;

Просмотреть файл

@ -130,8 +130,8 @@ class Context
void bindPixelPackBuffer(GLuint buffer);
void bindPixelUnpackBuffer(GLuint buffer);
void useProgram(GLuint program);
void linkProgram(GLuint program);
void setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length);
Error linkProgram(GLuint program);
Error setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length);
void bindTransformFeedback(GLuint transformFeedback);
Error beginQuery(GLenum target, GLuint query);

Просмотреть файл

@ -48,6 +48,11 @@ ImageIndex ImageIndex::Make3D(GLint mipIndex, GLint layerIndex)
return ImageIndex(GL_TEXTURE_3D, mipIndex, layerIndex);
}
ImageIndex ImageIndex::MakeInvalid()
{
return ImageIndex(GL_NONE, -1, -1);
}
ImageIndex::ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn)
: type(typeIn),
mipIndex(mipIndexIn),

Просмотреть файл

@ -31,6 +31,7 @@ struct ImageIndex
static ImageIndex MakeCube(GLenum target, GLint mipIndex);
static ImageIndex Make2DArray(GLint mipIndex, GLint layerIndex);
static ImageIndex Make3D(GLint mipIndex, GLint layerIndex = ENTIRE_LEVEL);
static ImageIndex MakeInvalid();
static const GLint ENTIRE_LEVEL = static_cast<GLint>(-1);
};

Просмотреть файл

@ -244,7 +244,7 @@ void Program::bindAttributeLocation(GLuint index, const char *name)
// Links the HLSL code of the vertex and pixel shader by matching up their varyings,
// compiling them into binaries, determining the attribute mappings, and collecting
// a list of uniforms
bool Program::link(const Caps &caps)
Error Program::link(const Caps &caps)
{
unlink(false);
@ -252,10 +252,15 @@ bool Program::link(const Caps &caps)
resetUniformBlockBindings();
mProgramBinary.set(new ProgramBinary(mRenderer->createProgram()));
mLinked = mProgramBinary->link(mInfoLog, mAttributeBindings, mFragmentShader, mVertexShader,
mTransformFeedbackVaryings, mTransformFeedbackBufferMode, caps);
LinkResult result = mProgramBinary->link(mInfoLog, mAttributeBindings, mFragmentShader, mVertexShader,
mTransformFeedbackVaryings, mTransformFeedbackBufferMode, caps);
if (result.error.isError())
{
return result.error;
}
return mLinked;
mLinked = result.linkSuccess;
return gl::Error(GL_NO_ERROR);
}
int AttributeBindings::getAttributeBinding(const std::string &name) const
@ -303,21 +308,22 @@ ProgramBinary* Program::getProgramBinary() const
return mProgramBinary.get();
}
bool Program::setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length)
Error Program::setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length)
{
unlink(false);
mInfoLog.reset();
mProgramBinary.set(new ProgramBinary(mRenderer->createProgram()));
mLinked = mProgramBinary->load(mInfoLog, binaryFormat, binary, length);
if (!mLinked)
LinkResult result = mProgramBinary->load(mInfoLog, binaryFormat, binary, length);
if (result.error.isError())
{
mProgramBinary.set(NULL);
return result.error;
}
return mLinked;
mLinked = result.linkSuccess;
return Error(GL_NO_ERROR);
}
void Program::release()

Просмотреть файл

@ -77,9 +77,9 @@ class Program
void bindAttributeLocation(GLuint index, const char *name);
bool link(const Caps &caps);
Error link(const Caps &caps);
bool isLinked();
bool setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length);
Error setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length);
ProgramBinary *getProgramBinary() const;
int getInfoLogLength() const;

Просмотреть файл

@ -107,6 +107,12 @@ LinkedVarying::LinkedVarying(const std::string &name, GLenum type, GLsizei size,
{
}
LinkResult::LinkResult(bool linkSuccess, const Error &error)
: linkSuccess(linkSuccess),
error(error)
{
}
unsigned int ProgramBinary::mCurrentSerial = 1;
ProgramBinary::ProgramBinary(rx::ProgramImpl *impl)
@ -854,10 +860,10 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shade
return true;
}
bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length)
LinkResult ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length)
{
#ifdef ANGLE_DISABLE_PROGRAM_BINARY_LOAD
return false;
return LinkResult(false, Error(GL_NO_ERROR));
#else
ASSERT(binaryFormat == mProgram->getBinaryFormat());
@ -869,7 +875,7 @@ bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *bina
if (format != mProgram->getBinaryFormat())
{
infoLog.append("Invalid program binary format.");
return false;
return LinkResult(false, Error(GL_NO_ERROR));
}
int majorVersion = stream.readInt<int>();
@ -877,7 +883,7 @@ bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *bina
if (majorVersion != ANGLE_MAJOR_VERSION || minorVersion != ANGLE_MINOR_VERSION)
{
infoLog.append("Invalid program binary version.");
return false;
return LinkResult(false, Error(GL_NO_ERROR));
}
unsigned char commitString[ANGLE_COMMIT_HASH_SIZE];
@ -885,14 +891,14 @@ bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *bina
if (memcmp(commitString, ANGLE_COMMIT_HASH, sizeof(unsigned char) * ANGLE_COMMIT_HASH_SIZE) != 0)
{
infoLog.append("Invalid program binary version.");
return false;
return LinkResult(false, Error(GL_NO_ERROR));
}
int compileFlags = stream.readInt<int>();
if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL)
{
infoLog.append("Mismatched compilation flags.");
return false;
return LinkResult(false, Error(GL_NO_ERROR));
}
for (int i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
@ -932,7 +938,7 @@ bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *bina
if (stream.error())
{
infoLog.append("Invalid program binary.");
return false;
return LinkResult(false, Error(GL_NO_ERROR));
}
mUniforms.resize(uniformCount);
@ -965,7 +971,7 @@ bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *bina
if (stream.error())
{
infoLog.append("Invalid program binary.");
return false;
return LinkResult(false, Error(GL_NO_ERROR));
}
mUniformBlocks.resize(uniformBlockCount);
@ -994,7 +1000,7 @@ bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *bina
if (stream.error())
{
infoLog.append("Invalid program binary.");
return false;
return LinkResult(false, Error(GL_NO_ERROR));
}
mUniformIndex.resize(uniformIndexCount);
@ -1005,18 +1011,19 @@ bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *bina
stream.readInt(&mUniformIndex[uniformIndexIndex].index);
}
if (!mProgram->load(infoLog, &stream))
LinkResult result = mProgram->load(infoLog, &stream);
if (result.error.isError() || !result.linkSuccess)
{
return false;
return result;
}
mProgram->initializeUniformStorage(mUniforms);
return true;
return LinkResult(true, Error(GL_NO_ERROR));
#endif // #ifdef ANGLE_DISABLE_PROGRAM_BINARY_LOAD
}
bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length)
Error ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length)
{
if (binaryFormat)
{
@ -1108,15 +1115,7 @@ bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GL
stream.writeInt(mUniformIndex[i].index);
}
if (!mProgram->save(&stream))
{
if (length)
{
*length = 0;
}
return false;
}
mProgram->save(&stream);
GLsizei streamLength = stream.length();
const void *streamData = stream.data();
@ -1128,7 +1127,10 @@ bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GL
*length = 0;
}
return false;
// TODO: This should be moved to the validation layer but computing the size of the binary before saving
// it causes the save to happen twice. It may be possible to write the binary to a separate buffer, validate
// sizes and then copy it.
return Error(GL_INVALID_OPERATION);
}
if (binary)
@ -1146,34 +1148,33 @@ bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GL
*length = streamLength;
}
return true;
return Error(GL_NO_ERROR);
}
GLint ProgramBinary::getLength()
{
GLint length;
if (save(NULL, NULL, INT_MAX, &length))
{
return length;
}
else
Error error = save(NULL, NULL, INT_MAX, &length);
if (error.isError())
{
return 0;
}
return length;
}
bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBindings, Shader *fragmentShader, Shader *vertexShader,
const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode, const Caps &caps)
LinkResult ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBindings, Shader *fragmentShader, Shader *vertexShader,
const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode, const Caps &caps)
{
if (!fragmentShader || !fragmentShader->isCompiled())
{
return false;
return LinkResult(false, Error(GL_NO_ERROR));
}
ASSERT(fragmentShader->getType() == GL_FRAGMENT_SHADER);
if (!vertexShader || !vertexShader->isCompiled())
{
return false;
return LinkResult(false, Error(GL_NO_ERROR));
}
ASSERT(vertexShader->getType() == GL_VERTEX_SHADER);
@ -1187,22 +1188,21 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin
int registers;
std::vector<LinkedVarying> linkedVaryings;
if (!mProgram->link(infoLog, fragmentShader, vertexShader, transformFeedbackVaryings, transformFeedbackBufferMode,
&registers, &linkedVaryings, &mOutputVariables, caps))
LinkResult result = mProgram->link(infoLog, fragmentShader, vertexShader, transformFeedbackVaryings, transformFeedbackBufferMode,
&registers, &linkedVaryings, &mOutputVariables, caps);
if (result.error.isError() || !result.linkSuccess)
{
return false;
return result;
}
bool success = true;
if (!linkAttributes(infoLog, attributeBindings, vertexShader))
{
success = false;
return LinkResult(false, Error(GL_NO_ERROR));
}
if (!linkUniforms(infoLog, *vertexShader, *fragmentShader, caps))
{
success = false;
return LinkResult(false, Error(GL_NO_ERROR));
}
// special case for gl_DepthRange, the only built-in uniform (also a struct)
@ -1217,28 +1217,26 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin
if (!linkUniformBlocks(infoLog, *vertexShader, *fragmentShader, caps))
{
success = false;
return LinkResult(false, Error(GL_NO_ERROR));
}
if (!gatherTransformFeedbackLinkedVaryings(infoLog, linkedVaryings, transformFeedbackVaryings,
transformFeedbackBufferMode, &mProgram->getTransformFeedbackLinkedVaryings(), caps))
{
success = false;
return LinkResult(false, Error(GL_NO_ERROR));
}
if (success)
// TODO: The concept of "executables" is D3D only, and as such this belongs in ProgramD3D. It must be called,
// however, last in this function, so it can't simply be moved to ProgramD3D::link without further shuffling.
result = mProgram->compileProgramExecutables(infoLog, fragmentShader, vertexShader, registers);
if (result.error.isError() || !result.linkSuccess)
{
// TODO: The concept of "executables" is D3D only, and as such this belongs in ProgramD3D. It must be called,
// however, last in this function, so it can't simply be moved to ProgramD3D::link without further shuffling.
if (!mProgram->compileProgramExecutables(infoLog, fragmentShader, vertexShader, registers))
{
infoLog.append("Failed to create D3D shaders.");
success = false;
reset();
}
infoLog.append("Failed to create D3D shaders.");
reset();
return result;
}
return success;
return LinkResult(true, Error(GL_NO_ERROR));
}
// Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices

Просмотреть файл

@ -86,6 +86,14 @@ struct LinkedVarying
unsigned int semanticIndexCount;
};
struct LinkResult
{
bool linkSuccess;
Error error;
LinkResult(bool linkSuccess, const Error &error);
};
// This is the result of linking a program. It is the state that would be passed to ProgramBinary.
class ProgramBinary : public RefCountObject
{
@ -138,12 +146,13 @@ class ProgramBinary : public RefCountObject
Error applyUniforms();
Error applyUniformBuffers(const std::vector<Buffer*> boundBuffers, const Caps &caps);
bool load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length);
bool save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length);
LinkResult load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length);
Error save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length);
GLint getLength();
bool link(InfoLog &infoLog, const AttributeBindings &attributeBindings, Shader *fragmentShader, Shader *vertexShader,
const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode, const Caps &caps);
LinkResult link(InfoLog &infoLog, const AttributeBindings &attributeBindings, Shader *fragmentShader, Shader *vertexShader,
const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode,
const Caps &caps);
void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders);
void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;

Просмотреть файл

@ -22,6 +22,8 @@ namespace gl
State::State()
{
mMaxDrawBuffers = 0;
mMaxCombinedTextureImageUnits = 0;
}
State::~State()
@ -31,7 +33,8 @@ State::~State()
void State::initialize(const Caps& caps, GLuint clientVersion)
{
mContext = NULL;
mMaxDrawBuffers = caps.maxDrawBuffers;
mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
@ -111,11 +114,15 @@ void State::initialize(const Caps& caps, GLuint clientVersion)
mActiveSampler = 0;
const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
mVertexAttribCurrentValues.resize(caps.maxVertexAttributes);
for (size_t attribIndex = 0; attribIndex < mVertexAttribCurrentValues.size(); ++attribIndex)
{
mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
}
mUniformBuffers.resize(caps.maxCombinedUniformBlocks);
mTransformFeedbackBuffers.resize(caps.maxTransformFeedbackSeparateAttributes);
mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
if (clientVersion >= 3)
@ -153,12 +160,6 @@ void State::reset()
mSamplers[samplerIdx].set(NULL);
}
const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
{
mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
}
mArrayBuffer.set(NULL);
mRenderbuffer.set(NULL);
@ -170,15 +171,15 @@ void State::reset()
}
mGenericUniformBuffer.set(NULL);
for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++)
mGenericTransformFeedbackBuffer.set(NULL);
for (BufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr)
{
mUniformBuffers[i].set(NULL);
bufItr->set(NULL);
}
mGenericTransformFeedbackBuffer.set(NULL);
for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
for (BufferVector::iterator bufItr = mTransformFeedbackBuffers.begin(); bufItr != mTransformFeedbackBuffers.end(); ++bufItr)
{
mTransformFeedbackBuffers[i].set(NULL);
bufItr->set(NULL);
}
mCopyReadBuffer.set(NULL);
@ -947,14 +948,14 @@ void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintpt
GLuint State::getIndexedUniformBufferId(GLuint index) const
{
ASSERT(index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS);
ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
return mUniformBuffers[index].id();
}
Buffer *State::getIndexedUniformBuffer(GLuint index) const
{
ASSERT(index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS);
ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
return mUniformBuffers[index].get();
}
@ -971,25 +972,30 @@ void State::setIndexedTransformFeedbackBufferBinding(GLuint index, Buffer *buffe
GLuint State::getIndexedTransformFeedbackBufferId(GLuint index) const
{
ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size());
return mTransformFeedbackBuffers[index].id();
}
Buffer *State::getIndexedTransformFeedbackBuffer(GLuint index) const
{
ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size());
return mTransformFeedbackBuffers[index].get();
}
GLuint State::getIndexedTransformFeedbackBufferOffset(GLuint index) const
{
ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size());
return mTransformFeedbackBuffers[index].getOffset();
}
size_t State::getTransformFeedbackBufferIndexRange() const
{
return mTransformFeedbackBuffers.size();
}
void State::setCopyReadBufferBinding(Buffer *buffer)
{
mCopyReadBuffer.set(buffer);
@ -1033,19 +1039,19 @@ void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
void State::setVertexAttribf(GLuint index, const GLfloat values[4])
{
ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
mVertexAttribCurrentValues[index].setFloatValues(values);
}
void State::setVertexAttribu(GLuint index, const GLuint values[4])
{
ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
}
void State::setVertexAttribi(GLuint index, const GLint values[4])
{
ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
mVertexAttribCurrentValues[index].setIntValues(values);
}
@ -1062,15 +1068,10 @@ const VertexAttribute &State::getVertexAttribState(unsigned int attribNum) const
const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
{
ASSERT(attribNum < MAX_VERTEX_ATTRIBS);
ASSERT(static_cast<size_t>(attribNum) < mVertexAttribCurrentValues.size());
return mVertexAttribCurrentValues[attribNum];
}
const VertexAttribCurrentValueData *State::getVertexAttribCurrentValues() const
{
return mVertexAttribCurrentValues;
}
const void *State::getVertexAttribPointer(unsigned int attribNum) const
{
return getVertexArray()->getVertexAttribute(attribNum).pointer;
@ -1185,7 +1186,7 @@ void State::getIntegerv(GLenum pname, GLint *params)
if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
{
unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
ASSERT(colorAttachment < mContext->getCaps().maxDrawBuffers);
ASSERT(colorAttachment < mMaxDrawBuffers);
Framebuffer *framebuffer = mDrawFramebuffer;
*params = framebuffer->getDrawBufferState(colorAttachment);
return;
@ -1332,19 +1333,19 @@ void State::getIntegerv(GLenum pname, GLint *params)
}
break;
case GL_TEXTURE_BINDING_2D:
ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
*params = mSamplerTextures.at(GL_TEXTURE_2D)[mActiveSampler].id();
break;
case GL_TEXTURE_BINDING_CUBE_MAP:
ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
*params = mSamplerTextures.at(GL_TEXTURE_CUBE_MAP)[mActiveSampler].id();
break;
case GL_TEXTURE_BINDING_3D:
ASSERT(mActiveSampler <mContext->getCaps().maxCombinedTextureImageUnits);
ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
*params = mSamplerTextures.at(GL_TEXTURE_3D)[mActiveSampler].id();
break;
case GL_TEXTURE_BINDING_2D_ARRAY:
ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
*params = mSamplerTextures.at(GL_TEXTURE_2D_ARRAY)[mActiveSampler].id();
break;
case GL_UNIFORM_BUFFER_BINDING:
@ -1376,13 +1377,13 @@ bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
switch (target)
{
case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size())
{
*data = mTransformFeedbackBuffers[index].id();
}
break;
case GL_UNIFORM_BUFFER_BINDING:
if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
if (static_cast<size_t>(index) < mUniformBuffers.size())
{
*data = mUniformBuffers[index].id();
}
@ -1399,25 +1400,25 @@ bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
switch (target)
{
case GL_TRANSFORM_FEEDBACK_BUFFER_START:
if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size())
{
*data = mTransformFeedbackBuffers[index].getOffset();
}
break;
case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size())
{
*data = mTransformFeedbackBuffers[index].getSize();
}
break;
case GL_UNIFORM_BUFFER_START:
if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
if (static_cast<size_t>(index) < mUniformBuffers.size())
{
*data = mUniformBuffers[index].getOffset();
}
break;
case GL_UNIFORM_BUFFER_SIZE:
if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
if (static_cast<size_t>(index) < mUniformBuffers.size())
{
*data = mUniformBuffers[index].getSize();
}
@ -1433,9 +1434,9 @@ bool State::hasMappedBuffer(GLenum target) const
{
if (target == GL_ARRAY_BUFFER)
{
for (unsigned int attribIndex = 0; attribIndex < gl::MAX_VERTEX_ATTRIBS; attribIndex++)
for (size_t attribIndex = 0; attribIndex < mVertexAttribCurrentValues.size(); attribIndex++)
{
const gl::VertexAttribute &vertexAttrib = getVertexAttribState(attribIndex);
const gl::VertexAttribute &vertexAttrib = getVertexAttribState(static_cast<unsigned int>(attribIndex));
gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
{

Просмотреть файл

@ -35,8 +35,6 @@ class State
void initialize(const Caps& caps, GLuint clientVersion);
void reset();
void setContext(Context *context) { mContext = context; }
// State chunk getters
const RasterizerState &getRasterizerState() const;
const BlendState &getBlendState() const;
@ -199,6 +197,7 @@ class State
GLuint getIndexedTransformFeedbackBufferId(GLuint index) const;
Buffer *getIndexedTransformFeedbackBuffer(GLuint index) const;
GLuint getIndexedTransformFeedbackBufferOffset(GLuint index) const;
size_t getTransformFeedbackBufferIndexRange() const;
// GL_COPY_[READ/WRITE]_BUFFER
void setCopyReadBufferBinding(Buffer *buffer);
@ -220,7 +219,6 @@ class State
bool normalized, bool pureInteger, GLsizei stride, const void *pointer);
const VertexAttribute &getVertexAttribState(unsigned int attribNum) const;
const VertexAttribCurrentValueData &getVertexAttribCurrentValue(unsigned int attribNum) const;
const VertexAttribCurrentValueData *getVertexAttribCurrentValues() const;
const void *getVertexAttribPointer(unsigned int attribNum) const;
// Pixel pack state manipulation
@ -247,7 +245,9 @@ class State
private:
DISALLOW_COPY_AND_ASSIGN(State);
Context *mContext;
// Cached values from Context's caps
GLuint mMaxDrawBuffers;
GLuint mMaxCombinedTextureImageUnits;
ColorF mColorClearValue;
GLclampf mDepthClearValue;
@ -283,7 +283,8 @@ class State
GLuint mCurrentProgramId;
BindingPointer<ProgramBinary> mCurrentProgramBinary;
VertexAttribCurrentValueData mVertexAttribCurrentValues[MAX_VERTEX_ATTRIBS]; // From glVertexAttrib
typedef std::vector<VertexAttribCurrentValueData> VertexAttribVector;
VertexAttribVector mVertexAttribCurrentValues; // From glVertexAttrib
VertexArray *mVertexArray;
// Texture and sampler bindings
@ -300,11 +301,12 @@ class State
ActiveQueryMap mActiveQueries;
BindingPointer<Buffer> mGenericUniformBuffer;
OffsetBindingPointer<Buffer> mUniformBuffers[IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS];
typedef std::vector< OffsetBindingPointer<Buffer> > BufferVector;
BufferVector mUniformBuffers;
BindingPointer<TransformFeedback> mTransformFeedback;
BindingPointer<Buffer> mGenericTransformFeedbackBuffer;
OffsetBindingPointer<Buffer> mTransformFeedbackBuffers[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
BufferVector mTransformFeedbackBuffers;
BindingPointer<Buffer> mCopyReadBuffer;
BindingPointer<Buffer> mCopyWriteBuffer;

Просмотреть файл

@ -9,6 +9,8 @@
#include "libGLESv2/angletypes.h"
#include "libGLESv2/ProgramBinary.h"
#include "libGLESv2/VertexAttribute.h"
#include "libGLESv2/State.h"
#include "libGLESv2/VertexArray.h"
namespace gl
{
@ -148,16 +150,16 @@ VertexFormat::VertexFormat(const VertexAttribute &attrib, GLenum currentValueTyp
void VertexFormat::GetInputLayout(VertexFormat *inputLayout,
ProgramBinary *programBinary,
const VertexAttribute *attributes,
const gl::VertexAttribCurrentValueData *currentValues)
const State &state)
{
const VertexAttribute *vertexAttributes = state.getVertexArray()->getVertexAttributes();
for (unsigned int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
{
int semanticIndex = programBinary->getSemanticIndex(attributeIndex);
if (semanticIndex != -1)
{
inputLayout[semanticIndex] = VertexFormat(attributes[attributeIndex], currentValues[attributeIndex].Type);
inputLayout[semanticIndex] = VertexFormat(vertexAttributes[attributeIndex], state.getVertexAttribCurrentValue(attributeIndex).Type);
}
}
}

Просмотреть файл

@ -15,6 +15,7 @@
namespace gl
{
class Buffer;
class State;
class ProgramBinary;
struct VertexAttribute;
struct VertexAttribCurrentValueData;
@ -229,8 +230,7 @@ struct VertexFormat
static void GetInputLayout(VertexFormat *inputLayout,
ProgramBinary *programBinary,
const VertexAttribute *attributes,
const gl::VertexAttribCurrentValueData *currentValues);
const State& currentValues);
bool operator==(const VertexFormat &other) const;
bool operator!=(const VertexFormat &other) const;

Просмотреть файл

@ -3654,7 +3654,12 @@ void __stdcall glLinkProgram(GLuint program)
}
}
context->linkProgram(program);
gl::Error error = context->linkProgram(program);
if (error.isError())
{
context->recordError(error);
return;
}
}
}
@ -8402,9 +8407,10 @@ void __stdcall glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *l
return;
}
if (!programBinary->save(binaryFormat, binary, bufSize, length))
gl::Error error = programBinary->save(binaryFormat, binary, bufSize, length);
if (error.isError())
{
context->recordError(gl::Error(GL_INVALID_OPERATION));
context->recordError(error);
return;
}
}
@ -8433,7 +8439,12 @@ void __stdcall glProgramBinaryOES(GLuint program, GLenum binaryFormat,
return;
}
context->setProgramBinary(program, binaryFormat, binary, length);
gl::Error error = context->setProgramBinary(program, binaryFormat, binary, length);
if (error.isError())
{
context->recordError(error);
return;
}
}
}

Просмотреть файл

@ -9,6 +9,8 @@
// surfaces or resources.
#include "libGLESv2/renderer/Image.h"
#include "libGLESv2/Framebuffer.h"
#include "libGLESv2/main.h"
namespace rx
{
@ -25,4 +27,18 @@ Image::Image()
mDirty = false;
}
void Image::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &area, gl::Framebuffer *source)
{
gl::FramebufferAttachment *colorbuffer = source->getReadColorbuffer();
if (!colorbuffer)
{
return gl::error(GL_OUT_OF_MEMORY);
}
RenderTarget *renderTarget = GetAttachmentRenderTarget(colorbuffer);
ASSERT(renderTarget);
copy(xoffset, yoffset, zoffset, area, renderTarget);
}
}

Просмотреть файл

@ -19,12 +19,15 @@
namespace gl
{
class Framebuffer;
struct Rectangle;
struct ImageIndex;
}
namespace rx
{
class Renderer;
class RenderTarget;
class TextureStorage;
class Image
{
@ -51,7 +54,10 @@ class Image
virtual gl::Error loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
const void *input) = 0;
virtual void copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0;
void copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, gl::Framebuffer *source);
virtual void copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source) = 0;
virtual void copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea,
const gl::ImageIndex &sourceIndex, TextureStorage *source) = 0;
protected:
GLsizei mWidth;

Просмотреть файл

@ -32,16 +32,16 @@ public:
virtual sh::Attribute *getShaderAttributes() = 0;
virtual GLenum getBinaryFormat() = 0;
virtual bool load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) = 0;
virtual bool save(gl::BinaryOutputStream *stream) = 0;
virtual gl::LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) = 0;
virtual gl::Error save(gl::BinaryOutputStream *stream) = 0;
virtual bool compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
int registers) = 0;
virtual gl::LinkResult compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
int registers) = 0;
virtual bool link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
const std::vector<std::string> &transformFeedbackVaryings, GLenum transformFeedbackBufferMode,
int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
std::map<int, gl::VariableLocation> *outputVariables, const gl::Caps &caps) = 0;
virtual gl::LinkResult link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
const std::vector<std::string> &transformFeedbackVaryings, GLenum transformFeedbackBufferMode,
int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
std::map<int, gl::VariableLocation> *outputVariables, const gl::Caps &caps) = 0;
virtual void initializeUniformStorage(const std::vector<gl::LinkedUniform*> &uniforms) = 0;

Просмотреть файл

@ -132,10 +132,9 @@ class Renderer
bool rasterizerDiscard, bool transformFeedbackActive) = 0;
virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray) = 0;
virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount) = 0;
virtual gl::Error applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[],
GLint first, GLsizei count, GLsizei instances) = 0;
virtual gl::Error applyVertexBuffer(const gl::State &state, GLint first, GLsizei count, GLsizei instances) = 0;
virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) = 0;
virtual void applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]) = 0;
virtual void applyTransformFeedbackBuffers(const gl::State& state) = 0;
virtual gl::Error drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) = 0;
virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
@ -197,12 +196,13 @@ class Renderer
// Shader operations
virtual void releaseShaderCompiler() = 0;
virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type,
const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
bool separatedOutputBuffers) = 0;
virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, rx::ShaderType type,
const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
bool separatedOutputBuffers, D3DWorkaroundType workaround) = 0;
virtual gl::Error loadExecutable(const void *function, size_t length, rx::ShaderType type,
const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
bool separatedOutputBuffers, ShaderExecutable **outExecutable) = 0;
virtual gl::Error compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, rx::ShaderType type,
const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
bool separatedOutputBuffers, D3DWorkaroundType workaround,
ShaderExecutable **outExectuable) = 0;
virtual UniformStorage *createUniformStorage(size_t storageSize) = 0;
// Image operations

Просмотреть файл

@ -26,10 +26,12 @@ enum D3DWorkaroundType
struct Workarounds
{
Workarounds()
: mrtPerfWorkaround(false)
: mrtPerfWorkaround(false),
setDataFasterThanImageUpload(false)
{}
bool mrtPerfWorkaround;
bool setDataFasterThanImageUpload;
};
}

Просмотреть файл

@ -82,8 +82,8 @@ void HLSLCompiler::release()
}
}
ID3DBlob *HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string &hlsl, const std::string &profile,
const std::vector<CompileConfig> &configs) const
gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string &hlsl, const std::string &profile,
const std::vector<CompileConfig> &configs, ID3DBlob **outCompiledBlob) const
{
ASSERT(mD3DCompilerModule && mD3DCompileFunc);
@ -115,13 +115,15 @@ ID3DBlob *HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string
if (SUCCEEDED(result))
{
return binary;
*outCompiledBlob = binary;
return gl::Error(GL_NO_ERROR);
}
else
{
if (result == E_OUTOFMEMORY)
{
return gl::error<ID3DBlob*>(GL_OUT_OF_MEMORY, NULL);
*outCompiledBlob = NULL;
return gl::Error(GL_OUT_OF_MEMORY, "HLSL compiler had an unexpected failure, result: 0x%X.", result);
}
infoLog.append("Warning: D3D shader compilation failed with %s flags.", configs[i].name.c_str());
@ -133,7 +135,9 @@ ID3DBlob *HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string
}
}
return NULL;
// None of the configurations succeeded in compiling this shader but the compiler is still intact
*outCompiledBlob = NULL;
return gl::Error(GL_NO_ERROR);
}
}

Просмотреть файл

@ -1,6 +1,8 @@
#ifndef LIBGLESV2_RENDERER_HLSL_D3DCOMPILER_H_
#define LIBGLESV2_RENDERER_HLSL_D3DCOMPILER_H_
#include "libGLESv2/Error.h"
#include "common/angleutils.h"
#include "common/platform.h"
@ -33,8 +35,10 @@ class HLSLCompiler
bool initialize();
void release();
ID3DBlob *compileToBinary(gl::InfoLog &infoLog, const std::string &hlsl, const std::string &profile,
const std::vector<CompileConfig> &configs) const;
// Attempt to compile a HLSL shader using the supplied configurations, may output a NULL compiled blob
// even if no GL errors are returned.
gl::Error compileToBinary(gl::InfoLog &infoLog, const std::string &hlsl, const std::string &profile,
const std::vector<CompileConfig> &configs, ID3DBlob **outCompiledBlob) const;
private:
DISALLOW_COPY_AND_ASSIGN(HLSLCompiler);

Просмотреть файл

@ -17,6 +17,8 @@
namespace gl
{
class Framebuffer;
struct ImageIndex;
struct Box;
}
namespace rx
@ -37,10 +39,10 @@ class ImageD3D : public Image
virtual void setManagedSurfaceCube(TextureStorage *storage, int face, int level) {};
virtual void setManagedSurface3D(TextureStorage *storage, int level) {};
virtual void setManagedSurface2DArray(TextureStorage *storage, int layer, int level) {};
virtual gl::Error copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) = 0;
virtual gl::Error copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) = 0;
virtual gl::Error copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) = 0;
virtual gl::Error copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height) = 0;
virtual gl::Error copyToStorage2D(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region) = 0;
virtual gl::Error copyToStorageCube(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region) = 0;
virtual gl::Error copyToStorage3D(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region) = 0;
virtual gl::Error copyToStorage2DArray(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(ImageD3D);

Просмотреть файл

@ -147,7 +147,7 @@ bool ProgramD3D::usesGeometryShader() const
return usesPointSpriteEmulation();
}
bool ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
gl::LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
{
stream->readInt(&mShaderVersion);
@ -201,14 +201,22 @@ bool ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
unsigned int vertexShaderSize = stream->readInt<unsigned int>();
const unsigned char *vertexShaderFunction = binary + stream->offset();
ShaderExecutable *shaderExecutable = mRenderer->loadExecutable(vertexShaderFunction, vertexShaderSize,
SHADER_VERTEX,
mTransformFeedbackLinkedVaryings,
(mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
ShaderExecutable *shaderExecutable = NULL;
gl::Error error = mRenderer->loadExecutable(vertexShaderFunction, vertexShaderSize,
SHADER_VERTEX,
mTransformFeedbackLinkedVaryings,
(mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
&shaderExecutable);
if (error.isError())
{
return gl::LinkResult(false, error);
}
if (!shaderExecutable)
{
infoLog.append("Could not create vertex shader.");
return false;
return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
}
// generated converted input layout
@ -233,15 +241,20 @@ bool ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
const size_t pixelShaderSize = stream->readInt<unsigned int>();
const unsigned char *pixelShaderFunction = binary + stream->offset();
ShaderExecutable *shaderExecutable = mRenderer->loadExecutable(pixelShaderFunction, pixelShaderSize,
SHADER_PIXEL,
mTransformFeedbackLinkedVaryings,
(mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
ShaderExecutable *shaderExecutable = NULL;
gl::Error error = mRenderer->loadExecutable(pixelShaderFunction, pixelShaderSize, SHADER_PIXEL,
mTransformFeedbackLinkedVaryings,
(mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
&shaderExecutable);
if (error.isError())
{
return gl::LinkResult(false, error);
}
if (!shaderExecutable)
{
infoLog.append("Could not create pixel shader.");
return false;
return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
}
// add new binary
@ -255,15 +268,19 @@ bool ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
if (geometryShaderSize > 0)
{
const unsigned char *geometryShaderFunction = binary + stream->offset();
mGeometryExecutable = mRenderer->loadExecutable(geometryShaderFunction, geometryShaderSize,
SHADER_GEOMETRY,
mTransformFeedbackLinkedVaryings,
(mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
gl::Error error = mRenderer->loadExecutable(geometryShaderFunction, geometryShaderSize, SHADER_GEOMETRY,
mTransformFeedbackLinkedVaryings,
(mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
&mGeometryExecutable);
if (error.isError())
{
return gl::LinkResult(false, error);
}
if (!mGeometryExecutable)
{
infoLog.append("Could not create geometry shader.");
return false;
return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
}
stream->skip(geometryShaderSize);
}
@ -275,13 +292,13 @@ bool ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
if (memcmp(&identifier, &binaryIdentifier, sizeof(GUID)) != 0)
{
infoLog.append("Invalid program binary.");
return false;
return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
}
return true;
return gl::LinkResult(true, gl::Error(GL_NO_ERROR));
}
bool ProgramD3D::save(gl::BinaryOutputStream *stream)
gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream)
{
stream->writeInt(mShaderVersion);
@ -367,12 +384,12 @@ bool ProgramD3D::save(gl::BinaryOutputStream *stream)
}
GUID binaryIdentifier = mRenderer->getAdapterIdentifier();
stream->writeBytes(reinterpret_cast<unsigned char*>(&binaryIdentifier), sizeof(GUID));
stream->writeBytes(reinterpret_cast<unsigned char*>(&binaryIdentifier), sizeof(GUID));
return true;
return gl::Error(GL_NO_ERROR);
}
ShaderExecutable *ProgramD3D::getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo)
gl::Error ProgramD3D::getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo, ShaderExecutable **outExecutable)
{
std::vector<GLenum> outputs;
@ -392,16 +409,17 @@ ShaderExecutable *ProgramD3D::getPixelExecutableForFramebuffer(const gl::Framebu
}
}
return getPixelExecutableForOutputLayout(outputs);
return getPixelExecutableForOutputLayout(outputs, outExecutable);
}
ShaderExecutable *ProgramD3D::getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputSignature)
gl::Error ProgramD3D::getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputSignature, ShaderExecutable **outExectuable)
{
for (size_t executableIndex = 0; executableIndex < mPixelExecutables.size(); executableIndex++)
{
if (mPixelExecutables[executableIndex]->matchesSignature(outputSignature))
{
return mPixelExecutables[executableIndex]->shaderExecutable();
*outExectuable = mPixelExecutables[executableIndex]->shaderExecutable();
return gl::Error(GL_NO_ERROR);
}
}
@ -410,10 +428,15 @@ ShaderExecutable *ProgramD3D::getPixelExecutableForOutputLayout(const std::vecto
// Generate new pixel executable
gl::InfoLog tempInfoLog;
ShaderExecutable *pixelExecutable = mRenderer->compileToExecutable(tempInfoLog, finalPixelHLSL, SHADER_PIXEL,
mTransformFeedbackLinkedVaryings,
(mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
mPixelWorkarounds);
ShaderExecutable *pixelExecutable = NULL;
gl::Error error = mRenderer->compileToExecutable(tempInfoLog, finalPixelHLSL, SHADER_PIXEL,
mTransformFeedbackLinkedVaryings,
(mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
mPixelWorkarounds, &pixelExecutable);
if (error.isError())
{
return error;
}
if (!pixelExecutable)
{
@ -426,10 +449,11 @@ ShaderExecutable *ProgramD3D::getPixelExecutableForOutputLayout(const std::vecto
mPixelExecutables.push_back(new PixelExecutable(outputSignature, pixelExecutable));
}
return pixelExecutable;
*outExectuable = pixelExecutable;
return gl::Error(GL_NO_ERROR);
}
ShaderExecutable *ProgramD3D::getVertexExecutableForInputLayout(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS])
gl::Error ProgramD3D::getVertexExecutableForInputLayout(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], ShaderExecutable **outExectuable)
{
GLenum signature[gl::MAX_VERTEX_ATTRIBS];
getInputLayoutSignature(inputLayout, signature);
@ -438,7 +462,8 @@ ShaderExecutable *ProgramD3D::getVertexExecutableForInputLayout(const gl::Vertex
{
if (mVertexExecutables[executableIndex]->matchesSignature(signature))
{
return mVertexExecutables[executableIndex]->shaderExecutable();
*outExectuable = mVertexExecutables[executableIndex]->shaderExecutable();
return gl::Error(GL_NO_ERROR);
}
}
@ -447,11 +472,16 @@ ShaderExecutable *ProgramD3D::getVertexExecutableForInputLayout(const gl::Vertex
// Generate new vertex executable
gl::InfoLog tempInfoLog;
ShaderExecutable *vertexExecutable = mRenderer->compileToExecutable(tempInfoLog, finalVertexHLSL,
SHADER_VERTEX,
mTransformFeedbackLinkedVaryings,
(mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
mVertexWorkarounds);
ShaderExecutable *vertexExecutable = NULL;
gl::Error error = mRenderer->compileToExecutable(tempInfoLog, finalVertexHLSL, SHADER_VERTEX,
mTransformFeedbackLinkedVaryings,
(mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
mVertexWorkarounds, &vertexExecutable);
if (error.isError())
{
return error;
}
if (!vertexExecutable)
{
std::vector<char> tempCharBuffer(tempInfoLog.getLength()+3);
@ -463,39 +493,55 @@ ShaderExecutable *ProgramD3D::getVertexExecutableForInputLayout(const gl::Vertex
mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, vertexExecutable));
}
return vertexExecutable;
*outExectuable = vertexExecutable;
return gl::Error(GL_NO_ERROR);
}
bool ProgramD3D::compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
int registers)
gl::LinkResult ProgramD3D::compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
int registers)
{
ShaderD3D *vertexShaderD3D = ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
ShaderD3D *fragmentShaderD3D = ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
gl::VertexFormat defaultInputLayout[gl::MAX_VERTEX_ATTRIBS];
GetDefaultInputLayoutFromShader(vertexShader->getActiveAttributes(), defaultInputLayout);
ShaderExecutable *defaultVertexExecutable = getVertexExecutableForInputLayout(defaultInputLayout);
ShaderExecutable *defaultVertexExecutable = NULL;
gl::Error error = getVertexExecutableForInputLayout(defaultInputLayout, &defaultVertexExecutable);
if (error.isError())
{
return gl::LinkResult(false, error);
}
std::vector<GLenum> defaultPixelOutput = GetDefaultOutputLayoutFromShader(getPixelShaderKey());
ShaderExecutable *defaultPixelExecutable = getPixelExecutableForOutputLayout(defaultPixelOutput);
ShaderExecutable *defaultPixelExecutable = NULL;
error = getPixelExecutableForOutputLayout(defaultPixelOutput, &defaultPixelExecutable);
if (error.isError())
{
return gl::LinkResult(false, error);
}
if (usesGeometryShader())
{
std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL(registers, fragmentShaderD3D, vertexShaderD3D);
mGeometryExecutable = mRenderer->compileToExecutable(infoLog, geometryHLSL,
SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings,
(mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
ANGLE_D3D_WORKAROUND_NONE);
error = mRenderer->compileToExecutable(infoLog, geometryHLSL, SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings,
(mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
ANGLE_D3D_WORKAROUND_NONE, &mGeometryExecutable);
if (error.isError())
{
return gl::LinkResult(false, error);
}
}
return (defaultVertexExecutable && defaultPixelExecutable && (!usesGeometryShader() || mGeometryExecutable));
bool linkSuccess = (defaultVertexExecutable && defaultPixelExecutable && (!usesGeometryShader() || mGeometryExecutable));
return gl::LinkResult(linkSuccess, gl::Error(GL_NO_ERROR));
}
bool ProgramD3D::link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
const std::vector<std::string> &transformFeedbackVaryings, GLenum transformFeedbackBufferMode,
int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
std::map<int, gl::VariableLocation> *outputVariables, const gl::Caps &caps)
gl::LinkResult ProgramD3D::link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
const std::vector<std::string> &transformFeedbackVaryings, GLenum transformFeedbackBufferMode,
int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
std::map<int, gl::VariableLocation> *outputVariables, const gl::Caps &caps)
{
ShaderD3D *vertexShaderD3D = ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
ShaderD3D *fragmentShaderD3D = ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
@ -515,24 +561,24 @@ bool ProgramD3D::link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shad
if (*registers < 0)
{
return false;
return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
}
if (!gl::ProgramBinary::linkVaryings(infoLog, fragmentShader, vertexShader))
{
return false;
return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
}
if (!mDynamicHLSL->generateShaderLinkHLSL(infoLog, *registers, packing, mPixelHLSL, mVertexHLSL,
fragmentShaderD3D, vertexShaderD3D, transformFeedbackVaryings,
linkedVaryings, outputVariables, &mPixelShaderKey, &mUsesFragDepth))
{
return false;
return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
}
mUsesPointSize = vertexShaderD3D->usesPointSize();
return true;
return gl::LinkResult(true, gl::Error(GL_NO_ERROR));
}
void ProgramD3D::getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше