Merge inbound to central, a=merge

This commit is contained in:
Wes Kocher 2015-10-23 15:37:37 -07:00
commit 14a6b74252
226 changed files with 2563 additions and 1173 deletions

View File

@ -917,7 +917,7 @@ Swipe.prototype.compile = function Swipe_compile() {
let edge = EDGE * Utils.dpi;
if (Math.abs(deltaX) > Math.abs(deltaY)) {
// Horizontal swipe.
let startPoints = [touch.x1 for (touch of detail.touches)];
let startPoints = detail.touches.map(touch => touch.x1);
if (deltaX > 0) {
detail.type = type + 'right';
detail.edge = Math.min.apply(null, startPoints) <= edge;
@ -928,7 +928,7 @@ Swipe.prototype.compile = function Swipe_compile() {
}
} else {
// Vertical swipe.
let startPoints = [touch.y1 for (touch of detail.touches)];
let startPoints = detail.touches.map(touch => touch.y1);
if (deltaY > 0) {
detail.type = type + 'down';
detail.edge = Math.min.apply(null, startPoints) <= edge;

View File

@ -67,11 +67,13 @@ var OutputGenerator = {
if (this.outputOrder === OUTPUT_DESC_FIRST) {
contextStart.forEach(addOutput);
addOutput(aContext.accessible);
[addOutput(node) for // jshint ignore:line
(node of aContext.subtreeGenerator(true, ignoreSubtree))]; // jshint ignore:line
for (let node of aContext.subtreeGenerator(true, ignoreSubtree)) {
addOutput(node);
}
} else {
[addOutput(node) for // jshint ignore:line
(node of aContext.subtreeGenerator(false, ignoreSubtree))]; // jshint ignore:line
for (let node of aContext.subtreeGenerator(false, ignoreSubtree)) {
addOutput(node);
}
addOutput(aContext.accessible);
// If there are any documents in new ancestry, find a first one and place

View File

@ -684,7 +684,7 @@ this.Presentation = { // jshint ignore:line
'b2g': [VisualPresenter, B2GPresenter],
'browser': [VisualPresenter, B2GPresenter, AndroidPresenter]
};
this.presenters = [new P() for (P of presenterMap[Utils.MozBuildApp])]; // jshint ignore:line
this.presenters = presenterMap[Utils.MozBuildApp].map(P => new P());
return this.presenters;
},
@ -700,61 +700,58 @@ this.Presentation = { // jshint ignore:line
aPosition, aOldPosition, aStartOffset, aEndOffset);
this.displayedAccessibles.set(context.accessible.document.window, context);
return [p.pivotChanged(context, aReason, aIsUserInput)
for each (p in this.presenters)]; // jshint ignore:line
return this.presenters.map(p => p.pivotChanged(context, aReason, aIsUserInput));
},
actionInvoked: function Presentation_actionInvoked(aObject, aActionName) {
return [p.actionInvoked(aObject, aActionName) // jshint ignore:line
for each (p in this.presenters)]; // jshint ignore:line
return this.presenters.map(p => p.actionInvoked(aObject, aActionName));
},
textChanged: function Presentation_textChanged(aAccessible, aIsInserted,
aStartOffset, aLength, aText,
aModifiedText) {
return [p.textChanged(aAccessible, aIsInserted, aStartOffset, aLength, // jshint ignore:line
aText, aModifiedText) for each (p in this.presenters)]; // jshint ignore:line
return this.presenters.map(p => p.textChanged(aAccessible, aIsInserted,
aStartOffset, aLength,
aText, aModifiedText));
},
textSelectionChanged: function textSelectionChanged(aText, aStart, aEnd,
aOldStart, aOldEnd,
aIsFromUserInput) {
return [p.textSelectionChanged(aText, aStart, aEnd, aOldStart, aOldEnd, // jshint ignore:line
aIsFromUserInput) for each (p in this.presenters)]; // jshint ignore:line
return this.presenters.map(p => p.textSelectionChanged(aText, aStart, aEnd,
aOldStart, aOldEnd,
aIsFromUserInput));
},
nameChanged: function nameChanged(aAccessible) {
return [ p.nameChanged(aAccessible) for (p of this.presenters) ]; // jshint ignore:line
return this.presenters.map(p => p.nameChanged(aAccessible));
},
valueChanged: function valueChanged(aAccessible) {
return [ p.valueChanged(aAccessible) for (p of this.presenters) ]; // jshint ignore:line
return this.presenters.map(p => p.valueChanged(aAccessible));
},
tabStateChanged: function Presentation_tabStateChanged(aDocObj, aPageState) {
return [p.tabStateChanged(aDocObj, aPageState) // jshint ignore:line
for each (p in this.presenters)]; // jshint ignore:line
return this.presenters.map(p => p.tabStateChanged(aDocObj, aPageState));
},
viewportChanged: function Presentation_viewportChanged(aWindow) {
let context = this.displayedAccessibles.get(aWindow);
return [p.viewportChanged(aWindow, context) // jshint ignore:line
for each (p in this.presenters)]; // jshint ignore:line
return this.presenters.map(p => p.viewportChanged(aWindow, context));
},
editingModeChanged: function Presentation_editingModeChanged(aIsEditing) {
return [p.editingModeChanged(aIsEditing) for each (p in this.presenters)]; // jshint ignore:line
return this.presenters.map(p => p.editingModeChanged(aIsEditing));
},
announce: function Presentation_announce(aAnnouncement) {
// XXX: Typically each presenter uses the UtteranceGenerator,
// but there really isn't a point here.
return [p.announce(UtteranceGenerator.genForAnnouncement(aAnnouncement)) // jshint ignore:line
for each (p in this.presenters)]; // jshint ignore:line
return this.presenters.map(p => p.announce(UtteranceGenerator.genForAnnouncement(aAnnouncement)));
},
noMove: function Presentation_noMove(aMoveMethod) {
return [p.noMove(aMoveMethod) for each (p in this.presenters)]; // jshint ignore:line
return this.presenters.map(p => p.noMove(aMoveMethod));
},
liveRegion: function Presentation_liveRegion(aAccessible, aIsPolite, aIsHide,
@ -764,7 +761,7 @@ this.Presentation = { // jshint ignore:line
context = new PivotContext(aAccessible, null, -1, -1, true,
aIsHide ? true : false);
}
return [p.liveRegion(context, aIsPolite, aIsHide, aModifiedText) // jshint ignore:line
for (p of this.presenters)]; // jshint ignore:line
return this.presenters.map(p => p.liveRegion(context, aIsPolite, aIsHide,
aModifiedText));
}
};

View File

@ -211,11 +211,10 @@ this.Utils = { // jshint ignore:line
localize: function localize(aOutput) {
let outputArray = Array.isArray(aOutput) ? aOutput : [aOutput];
let localized =
[this.stringBundle.get(details) for (details of outputArray)]; // jshint ignore:line
outputArray.map(details => this.stringBundle.get(details));
// Clean up the white space.
let trimmed;
return [trimmed for (word of localized) if (word && // jshint ignore:line
(trimmed = word.trim()))]; // jshint ignore:line
return localized.filter(word => word).map(word => word.trim()).
filter(trimmed => trimmed);
},
get stringBundle() {
@ -834,9 +833,9 @@ PivotContext.prototype = {
*/
get newAncestry() {
if (!this._newAncestry) {
this._newAncestry = this._ignoreAncestry ? [] : [currentAncestor for ( // jshint ignore:line
[index, currentAncestor] of Iterator(this.currentAncestry)) if ( // jshint ignore:line
currentAncestor !== this.oldAncestry[index])]; // jshint ignore:line
this._newAncestry = this._ignoreAncestry ? [] :
this.currentAncestry.filter(
(currentAncestor, i) => currentAncestor !== this.oldAncestry[i]);
}
return this._newAncestry;
},
@ -862,9 +861,13 @@ PivotContext.prototype = {
if (include) {
if (aPreorder) {
yield child;
[yield node for (node of this._traverse(child, aPreorder, aStop))]; // jshint ignore:line
for (let node of this._traverse(child, aPreorder, aStop)) {
yield node;
}
} else {
[yield node for (node of this._traverse(child, aPreorder, aStop))]; // jshint ignore:line
for (let node of this._traverse(child, aPreorder, aStop)) {
yield node;
}
yield child;
}
}
@ -986,15 +989,13 @@ PivotContext.prototype = {
cellInfo.columnHeaders = [];
if (cellInfo.columnChanged && cellInfo.current.role !==
Roles.COLUMNHEADER) {
cellInfo.columnHeaders = [headers for (headers of getHeaders( // jshint ignore:line
cellInfo.current.columnHeaderCells))];
cellInfo.columnHeaders = [...getHeaders(cellInfo.current.columnHeaderCells)];
}
cellInfo.rowHeaders = [];
if (cellInfo.rowChanged &&
(cellInfo.current.role === Roles.CELL ||
cellInfo.current.role === Roles.MATHML_CELL)) {
cellInfo.rowHeaders = [headers for (headers of getHeaders( // jshint ignore:line
cellInfo.current.rowHeaderCells))];
cellInfo.rowHeaders = [...getHeaders(cellInfo.current.rowHeaderCells)];
}
this._cells.set(domNode, cellInfo);

View File

@ -166,7 +166,7 @@ var AccessFuTest = {
AccessFuTest.nextTest();
} else {
// Run all test functions synchronously.
[testFunc() for (testFunc of gTestFuncs)]; // jshint ignore:line
gTestFuncs.forEach(testFunc => testFunc());
AccessFuTest.finish();
}
});

View File

@ -65,7 +65,7 @@
}
},
action: function action() {
[hide(id) for (id of ["to_hide1", "to_hide2", "to_hide3", "to_hide4"])];
["to_hide1", "to_hide2", "to_hide3", "to_hide4"].forEach(id => hide(id));
}
}, {
expected: {
@ -76,8 +76,8 @@
}
},
action: function action() {
[hide(id) for (id of ["to_hide_descendant1", "to_hide_descendant2",
"to_hide_descendant3", "to_hide_descendant4"])];
["to_hide_descendant1", "to_hide_descendant2",
"to_hide_descendant3", "to_hide_descendant4"].forEach(id => hide(id));
}
}, {
expected: {
@ -88,7 +88,7 @@
}
},
action: function action() {
[show(id) for (id of ["to_show1", "to_show2", "to_show3", "to_show4"])];
["to_show1", "to_show2", "to_show3", "to_show4"].forEach(id => show(id));
}
}, {
expected: {
@ -99,8 +99,8 @@
}
},
action: function action() {
[show(id) for (id of ["to_show_descendant1", "to_show_descendant2",
"to_show_descendant3", "to_show_descendant4"])];
["to_show_descendant1", "to_show_descendant2",
"to_show_descendant3", "to_show_descendant4"].forEach(id => show(id));
}
}, {
expected: {
@ -111,8 +111,7 @@
}
},
action: function action() {
[ariaHide(id) for (id of ["to_hide5", "to_hide6", "to_hide7",
"to_hide8", "to_hide9"])];
["to_hide5", "to_hide6", "to_hide7", "to_hide8", "to_hide9"].forEach(id => ariaHide(id));
}
}, {
expected: {
@ -123,8 +122,8 @@
}
},
action: function action() {
[ariaHide(id) for (id of ["to_hide_descendant5", "to_hide_descendant6",
"to_hide_descendant7", "to_hide_descendant8"])];
["to_hide_descendant5", "to_hide_descendant6",
"to_hide_descendant7", "to_hide_descendant8"].forEach(id => ariaHide(id));
}
}, {
expected: {
@ -135,8 +134,7 @@
}
},
action: function action() {
[ariaShow(id) for (id of ["to_show5", "to_show6", "to_show7",
"to_show8", "to_show9"])];
["to_show5", "to_show6", "to_show7", "to_show8", "to_show9"].forEach(id => ariaShow(id));
}
}, {
expected: {
@ -147,8 +145,8 @@
}
},
action: function action() {
[ariaShow(id) for (id of ["to_show_descendant5", "to_show_descendant6",
"to_show_descendant7", "to_show_descendant8"])];
["to_show_descendant5", "to_show_descendant6",
"to_show_descendant7", "to_show_descendant8"].forEach(id => ariaShow(id));
}
}, {
expected: {
@ -181,7 +179,7 @@
}
},
action: function action() {
[show(id) for (id of ["to_show_live_off", "to_show_live_assertive"])];
["to_show_live_off", "to_show_live_assertive"].forEach(id => show(id));
}
}, {
expected: {
@ -192,8 +190,7 @@
}
},
action: function action() {
[ariaShow(id) for (id of ["to_show_live_off2",
"to_show_live_assertive2"])];
["to_show_live_off2", "to_show_live_assertive2"].forEach(id => ariaShow(id));
}
}, {
expected: {
@ -472,4 +469,4 @@
</div>
</div>
</body>
</html>
</html>

View File

@ -0,0 +1,16 @@
[
{
"size": 80458572,
"digest": "e5101f9dee1e462f6cbd3897ea57eede41d23981825c7b20d91d23ab461875d54d3dfc24999aa58a31e8b01f49fb3140e05ffe5af2957ef1d1afb89fd0dfe1ad",
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": true
},
{
"size": 12057960,
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"unpack": true
}
]

View File

@ -0,0 +1,16 @@
[
{
"size": 80458572,
"digest": "e5101f9dee1e462f6cbd3897ea57eede41d23981825c7b20d91d23ab461875d54d3dfc24999aa58a31e8b01f49fb3140e05ffe5af2957ef1d1afb89fd0dfe1ad",
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": true
},
{
"size": 12057960,
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"unpack": true
}
]

View File

@ -39,7 +39,7 @@
},
"b2g_manifest": "aries.xml",
"b2g_manifest_intree": true,
"additional_source_tarballs": ["backup-aries.tar.xz"],
"additional_source_tarballs": [],
"gecko_l10n_root": "https://hg.mozilla.org/l10n-central",
"gaia": {
"l10n": {

View File

@ -1,16 +1,16 @@
[
{
"size": 135359412,
"digest": "45e677c9606cc4eec44ef4761df47ff431df1ffad17a5c6d21ce700a1c47f79e87a4aa9f30ae47ff060bd64f5b775d995780d88211f9a759ffa0d076beb4816b",
"algorithm": "sha512",
"filename": "backup-aries.tar.xz",
"comment": "v18D"
},
{
"size": 80458572,
"digest": "e5101f9dee1e462f6cbd3897ea57eede41d23981825c7b20d91d23ab461875d54d3dfc24999aa58a31e8b01f49fb3140e05ffe5af2957ef1d1afb89fd0dfe1ad",
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": "True"
},
{
"size": 12057960,
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"unpack": true
}
]

View File

@ -0,0 +1,16 @@
[
{
"size": 80458572,
"digest": "e5101f9dee1e462f6cbd3897ea57eede41d23981825c7b20d91d23ab461875d54d3dfc24999aa58a31e8b01f49fb3140e05ffe5af2957ef1d1afb89fd0dfe1ad",
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": true
},
{
"size": 12057960,
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"unpack": true
}
]

View File

@ -5,5 +5,12 @@
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": "True"
},
{
"size": 12057960,
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"unpack": true
}
]

View File

@ -0,0 +1,16 @@
[
{
"size": 80458572,
"digest": "e5101f9dee1e462f6cbd3897ea57eede41d23981825c7b20d91d23ab461875d54d3dfc24999aa58a31e8b01f49fb3140e05ffe5af2957ef1d1afb89fd0dfe1ad",
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": true
},
{
"size": 12057960,
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"unpack": true
}
]

View File

@ -12,5 +12,12 @@
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": "True"
},
{
"size": 12057960,
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"unpack": true
}
]

View File

@ -10,5 +10,12 @@
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": "True"
},
{
"size": 12057960,
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"unpack": true
}
]

View File

@ -23,6 +23,13 @@
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": "True"
},
{
"size": 12057960,
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"unpack": true
}
]

View File

@ -23,6 +23,13 @@
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": "True"
},
{
"size": 12057960,
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"unpack": true
}
]

View File

@ -4,4 +4,12 @@
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": "True"
}]
},
{
"size": 12057960,
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"unpack": true
}
]

View File

@ -29,7 +29,7 @@
}
function finish() {
for each (let eventType in LISTEN_EVENTS) {
for (let eventType of LISTEN_EVENTS) {
gBrowser.removeEventListener(eventType, eventListener, true);
}
@ -43,7 +43,7 @@
function onLoad() {
gBrowser = document.getElementById("content");
for each (let eventType in LISTEN_EVENTS) {
for (let eventType of LISTEN_EVENTS) {
gBrowser.addEventListener(eventType, eventListener, true);
}

View File

@ -15,7 +15,7 @@
<script type="application/javascript"><![CDATA[
var imports = [ "SimpleTest", "is", "isnot", "ok", "snapshotWindow",
"compareSnapshots", "onerror" ];
for each (var name in imports) {
for (var name of imports) {
window[name] = window.opener.wrappedJSObject[name];
}

View File

@ -15,7 +15,7 @@
<script type="application/javascript"><![CDATA[
var imports = [ "SimpleTest", "is", "isnot", "ok"];
for each (var name in imports) {
for (var name of imports) {
window[name] = window.opener.wrappedJSObject[name];
}

View File

@ -28,7 +28,7 @@
window.opener.wrappedJSObject.SimpleTest.is(a, b, message);
}
function finish() {
for each (let eventType in LISTEN_EVENTS) {
for (let eventType of LISTEN_EVENTS) {
gBrowser.removeEventListener(eventType, eventListener, true);
}
@ -39,7 +39,7 @@
function onLoad() {
gBrowser = document.getElementById("content");
for each (let eventType in LISTEN_EVENTS) {
for (let eventType of LISTEN_EVENTS) {
gBrowser.addEventListener(eventType, eventListener, true);
}

View File

@ -32,7 +32,7 @@
window.opener.wrappedJSObject.SimpleTest.is(a, b, message);
}
function finish() {
for each (let eventType in LISTEN_EVENTS) {
for (let eventType of LISTEN_EVENTS) {
gBrowser.removeEventListener(eventType, eventListener, true);
}
@ -43,7 +43,7 @@
function onLoad() {
gBrowser = document.getElementById("content");
for each (let eventType in LISTEN_EVENTS) {
for (let eventType of LISTEN_EVENTS) {
gBrowser.addEventListener(eventType, eventListener, true);
}

View File

@ -9,7 +9,7 @@
<!-- test code goes here -->
<script type="application/javascript"><![CDATA[
var imports = [ "SimpleTest", "is", "isnot", "ok", "onerror" ];
for each (var name in imports) {
for (var name of imports) {
window[name] = window.opener.wrappedJSObject[name];
}

View File

@ -9,7 +9,7 @@
<!-- test code goes here -->
<script type="application/javascript"><![CDATA[
var imports = [ "SimpleTest", "is", "isnot", "ok", "onerror" ];
for each (var name in imports) {
for (var name of imports) {
window[name] = window.opener.wrappedJSObject[name];
}

View File

@ -29,7 +29,7 @@
}
function finish() {
for each (let eventType in LISTEN_EVENTS) {
for (let eventType of LISTEN_EVENTS) {
gBrowser.removeEventListener(eventType, eventListener, true);
}
@ -43,7 +43,7 @@
function onLoad() {
gBrowser = document.getElementById("content");
for each (let eventType in LISTEN_EVENTS) {
for (let eventType of LISTEN_EVENTS) {
gBrowser.addEventListener(eventType, eventListener, true);
}

View File

@ -3,7 +3,7 @@
*/
var imports = [ "SimpleTest", "is", "isnot", "ok", "onerror", "todo",
"todo_is", "todo_isnot" ];
for each (var name in imports) {
for (var name of imports) {
window[name] = window.opener.wrappedJSObject[name];
}
@ -125,17 +125,21 @@ function doPageNavigation(params) {
throw "Must specify onNavComplete when specifying waitForEventsOnly";
if (waitOnly && (back || forward || reload || uri))
throw "Can't specify a navigation type when using waitForEventsOnly";
for each (let anEventType in eventsToListenFor) {
for (let anEventType of eventsToListenFor) {
let eventFound = false;
if ( (anEventType == "pageshow") && (!gExpectedEvents) )
eventFound = true;
for each (let anExpectedEvent in gExpectedEvents) {
if (anExpectedEvent.type == anEventType)
eventFound = true;
if (gExpectedEvents) {
for (let anExpectedEvent of gExpectedEvents) {
if (anExpectedEvent.type == anEventType)
eventFound = true;
}
}
for each (let anExpectedEventType in gUnexpectedEvents) {
if (anExpectedEventType == anEventType)
eventFound = true;
if (gUnexpectedEvents) {
for (let anExpectedEventType of gUnexpectedEvents) {
if (anExpectedEventType == anEventType)
eventFound = true;
}
}
if (!eventFound)
throw "Event type " + anEventType + " is specified in " +
@ -148,7 +152,7 @@ function doPageNavigation(params) {
// Add an event listener for each type of event in the .eventsToListenFor
// property of the input parameters.
for each (let eventType in eventsToListenFor) {
for (let eventType of eventsToListenFor) {
dump("TEST: registering a listener for " + eventType + " events\n");
TestWindow.getBrowser().addEventListener(eventType, pageEventListener,
true);
@ -201,7 +205,7 @@ function doPageNavigation_complete(eventsToListenFor, onNavComplete,
preventBFCache) {
// Unregister our event listeners.
dump("TEST: removing event listeners\n");
for each (let eventType in eventsToListenFor) {
for (let eventType of eventsToListenFor) {
TestWindow.getBrowser().removeEventListener(eventType, pageEventListener,
true);
}

View File

@ -97,6 +97,8 @@
#include "mozilla/dom/ipc/StructuredCloneData.h"
#include "mozilla/WebBrowserPersistLocalDocument.h"
#include "nsPrincipal.h"
#ifdef MOZ_XUL
#include "nsXULPopupManager.h"
#endif
@ -278,13 +280,20 @@ nsFrameLoader::LoadURI(nsIURI* aURI)
}
NS_IMETHODIMP
nsFrameLoader::SwitchProcessAndLoadURI(nsIURI* aURI)
nsFrameLoader::SwitchProcessAndLoadURI(nsIURI* aURI, const nsACString& aPackageId)
{
nsCOMPtr<nsIURI> URIToLoad = aURI;
RefPtr<TabParent> tp = nullptr;
nsCString signedPkgOrigin;
if (!aPackageId.IsEmpty()) {
// Only when aPackageId is not empty would signed package origin
// be meaningful.
nsPrincipal::GetOriginForURI(aURI, signedPkgOrigin);
}
MutableTabContext context;
nsresult rv = GetNewTabContext(&context);
nsresult rv = GetNewTabContext(&context, signedPkgOrigin, aPackageId);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<Element> ownerElement = mOwnerContent;
@ -3031,7 +3040,9 @@ nsFrameLoader::MaybeUpdatePrimaryTabParent(TabParentChange aChange)
}
nsresult
nsFrameLoader::GetNewTabContext(MutableTabContext* aTabContext)
nsFrameLoader::GetNewTabContext(MutableTabContext* aTabContext,
const nsACString& aSignedPkgOriginNoSuffix,
const nsACString& aPackageId)
{
nsCOMPtr<mozIApplication> ownApp = GetOwnApp();
nsCOMPtr<mozIApplication> containingApp = GetContainingApp();
@ -3051,7 +3062,11 @@ nsFrameLoader::GetNewTabContext(MutableTabContext* aTabContext)
}
attrs.mAppId = appId;
bool tabContextUpdated = aTabContext->SetTabContext(ownApp, containingApp, attrs);
// Populate packageId to signedPkg.
attrs.mSignedPkg = NS_ConvertUTF8toUTF16(aPackageId);
bool tabContextUpdated = aTabContext->SetTabContext(ownApp, containingApp,
attrs, aSignedPkgOriginNoSuffix);
NS_ENSURE_STATE(tabContextUpdated);
return NS_OK;

View File

@ -318,7 +318,9 @@ private:
void InitializeBrowserAPI();
nsresult GetNewTabContext(mozilla::dom::MutableTabContext* aTabContext);
nsresult GetNewTabContext(mozilla::dom::MutableTabContext* aTabContext,
const nsACString& aSignedPkgNoSuffix = EmptyCString(),
const nsACString& aPackageId = EmptyCString());
enum TabParentChange {
eTabParentRemoved,

View File

@ -191,6 +191,7 @@
#include "mozilla/dom/VRDevice.h"
#include "nsRefreshDriver.h"
#include "Layers.h"
#include "mozilla/AddonPathService.h"
#include "mozilla/BasePrincipal.h"

View File

@ -16,7 +16,7 @@ interface nsIDOMElement;
interface nsITabParent;
interface nsILoadContext;
[scriptable, builtinclass, uuid(c6e00815-b7a1-4544-b309-a85b86cb1747)]
[scriptable, builtinclass, uuid(1645af04-1bc7-4363-8f2c-eb9679220ab1)]
interface nsIFrameLoader : nsISupports
{
/**
@ -52,10 +52,11 @@ interface nsIFrameLoader : nsISupports
/**
* Loads the specified URI in this frame but using a different process.
* Behaves identically to loadURI, except that this method only works
* with remote frame.
* with remote frame. For a signed package, we need to specifiy the
* package identifier.
* Throws an exception with non-remote frames.
*/
void switchProcessAndLoadURI(in nsIURI aURI);
void switchProcessAndLoadURI(in nsIURI aURI, in ACString aPackageId);
/**
* Puts the frameloader in prerendering mode.

View File

@ -30,7 +30,7 @@
.QueryInterface(Ci.nsIFrameLoaderOwner)
.frameLoader;
var uri = SpecialPowers.Services.io.newURI(url, null, null);
fl.switchProcessAndLoadURI(uri);
fl.switchProcessAndLoadURI(uri, "");
}
function runTest() {

View File

@ -37,6 +37,7 @@
#include "mozilla/dom/CameraFacesDetectedEventBinding.h"
#include "mozilla/dom/CameraStateChangeEvent.h"
#include "mozilla/dom/CameraClosedEvent.h"
#include "mozilla/dom/VideoStreamTrack.h"
#include "mozilla/dom/BlobEvent.h"
#include "DOMCameraDetectedFace.h"
#include "mozilla/dom/BindingUtils.h"
@ -46,6 +47,45 @@ using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::ipc;
class mozilla::TrackCreatedListener : public MediaStreamListener
{
public:
explicit TrackCreatedListener(nsDOMCameraControl* aCameraControl)
: mCameraControl(aCameraControl) {}
void Forget() { mCameraControl = nullptr; }
void DoNotifyTrackCreated(TrackID aTrackID)
{
MOZ_ASSERT(NS_IsMainThread());
if (!mCameraControl) {
return;
}
mCameraControl->TrackCreated(aTrackID);
}
void NotifyQueuedTrackChanges(MediaStreamGraph* aGraph, TrackID aID,
StreamTime aTrackOffset, uint32_t aTrackEvents,
const MediaSegment& aQueuedMedia,
MediaStream* aInputStream,
TrackID aInputTrackID) override
{
if (aTrackEvents & TRACK_EVENT_CREATED) {
nsCOMPtr<nsIRunnable> runnable =
NS_NewRunnableMethodWithArgs<TrackID>(
this, &TrackCreatedListener::DoNotifyTrackCreated, aID);
aGraph->DispatchToMainThreadAfterStreamStateUpdate(runnable.forget());
}
}
protected:
~TrackCreatedListener() {}
nsDOMCameraControl* mCameraControl;
};
#ifdef MOZ_WIDGET_GONK
StaticRefPtr<ICameraControl> nsDOMCameraControl::sCachedCameraControl;
/* static */ nsresult nsDOMCameraControl::sCachedCameraControlStartResult = NS_OK;
@ -279,6 +319,11 @@ nsDOMCameraControl::nsDOMCameraControl(uint32_t aCameraId,
#endif
mCurrentConfiguration = initialConfig.forget();
// Register a TrackCreatedListener directly on CameraPreviewMediaStream
// so we can know the TrackID of the video track.
mTrackCreatedListener = new TrackCreatedListener(this);
mInput->AddListener(mTrackCreatedListener);
// Register the playback listener directly on the camera input stream.
// We want as low latency as possible for the camera, thus avoiding
// MediaStreamGraph altogether. Don't do the regular InitStreamCommon()
@ -334,6 +379,10 @@ nsDOMCameraControl::~nsDOMCameraControl()
mInput->Destroy();
mInput = nullptr;
}
if (mTrackCreatedListener) {
mTrackCreatedListener->Forget();
mTrackCreatedListener = nullptr;
}
}
JSObject*
@ -475,6 +524,19 @@ nsDOMCameraControl::GetCameraStream() const
return mInput;
}
void
nsDOMCameraControl::TrackCreated(TrackID aTrackID) {
// This track is not connected through a port.
MediaInputPort* inputPort = nullptr;
dom::VideoStreamTrack* track =
new dom::VideoStreamTrack(this, aTrackID);
RefPtr<TrackPort> port =
new TrackPort(inputPort, track,
TrackPort::InputPortOwnership::OWNED);
mTracks.AppendElement(port.forget());
NotifyTrackAdded(track);
}
#define THROW_IF_NO_CAMERACONTROL(...) \
do { \
if (!mCameraControl) { \

View File

@ -40,6 +40,7 @@ namespace dom {
class ErrorResult;
class StartRecordingHelper;
class RecorderPosterHelper;
class TrackCreatedListener;
#define NS_DOM_CAMERA_CONTROL_CID \
{ 0x3700c096, 0xf920, 0x438d, \
@ -73,6 +74,10 @@ public:
MediaStream* GetCameraStream() const override;
// Called by TrackCreatedListener when the underlying track has been created.
// XXX Bug 1124630. This can be removed with CameraPreviewMediaStream.
void TrackCreated(TrackID aTrackID);
// Attributes.
void GetEffect(nsString& aEffect, ErrorResult& aRv);
void SetEffect(const nsAString& aEffect, ErrorResult& aRv);
@ -226,6 +231,9 @@ protected:
// our viewfinder stream
RefPtr<CameraPreviewMediaStream> mInput;
// A listener on mInput for adding tracks to the DOM side.
RefPtr<TrackCreatedListener> mTrackCreatedListener;
// set once when this object is created
nsCOMPtr<nsPIDOMWindow> mWindow;

View File

@ -60,6 +60,7 @@
#include "nsBidi.h"
#include "nsBidiPresUtils.h"
#include "Layers.h"
#include "LayerUserData.h"
#include "CanvasUtils.h"
#include "nsIMemoryReporter.h"
#include "nsStyleUtil.h"

View File

@ -73,6 +73,7 @@ WebGL2Context::ClearBufferfv_base(GLenum buffer, GLint drawbuffer, const GLfloat
void
WebGL2Context::ClearBufferiv(GLenum buffer, GLint drawbuffer, const dom::Int32Array& value)
{
value.ComputeLengthAndData();
if (!ValidateClearBuffer("clearBufferiv", buffer, drawbuffer, value.Length())) {
return;
}
@ -93,6 +94,7 @@ WebGL2Context::ClearBufferiv(GLenum buffer, GLint drawbuffer, const dom::Sequenc
void
WebGL2Context::ClearBufferuiv(GLenum buffer, GLint drawbuffer, const dom::Uint32Array& value)
{
value.ComputeLengthAndData();
if (!ValidateClearBuffer("clearBufferuiv", buffer, drawbuffer, value.Length())) {
return;
}
@ -113,6 +115,7 @@ WebGL2Context::ClearBufferuiv(GLenum buffer, GLint drawbuffer, const dom::Sequen
void
WebGL2Context::ClearBufferfv(GLenum buffer, GLint drawbuffer, const dom::Float32Array& value)
{
value.ComputeLengthAndData();
if (!ValidateClearBuffer("clearBufferfv", buffer, drawbuffer, value.Length())) {
return;
}

View File

@ -21,6 +21,7 @@
#include "ImageContainer.h"
#include "ImageEncoder.h"
#include "Layers.h"
#include "LayerUserData.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/Event.h"
#include "mozilla/dom/HTMLVideoElement.h"

View File

@ -2113,7 +2113,8 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNo
mPlayBlockedBecauseHidden(false),
mMediaStreamTrackListener(nullptr),
mElementInTreeState(ELEMENT_NOT_INTREE),
mHasUserInteraction(false)
mHasUserInteraction(false),
mFirstFrameLoaded(false)
{
if (!gMediaElementLog) {
gMediaElementLog = PR_NewLogModule("nsMediaElement");
@ -3445,6 +3446,11 @@ void HTMLMediaElement::FirstFrameLoaded()
{
NS_ASSERTION(!mSuspendedAfterFirstFrame, "Should not have already suspended");
if (!mFirstFrameLoaded) {
mFirstFrameLoaded = true;
UpdateReadyStateInternal();
}
ChangeDelayLoadStatus(false);
if (mDecoder && mAllowSuspendAfterFirstFrame && mPaused &&
@ -3781,7 +3787,8 @@ HTMLMediaElement::UpdateReadyStateInternal()
return;
}
if (mDownloadSuspendedByCache && mDecoder && !mDecoder->IsEndedOrShutdown()) {
if (mDownloadSuspendedByCache && mDecoder && !mDecoder->IsEndedOrShutdown() &&
mFirstFrameLoaded) {
// The decoder has signaled that the download has been suspended by the
// media cache. So move readyState into HAVE_ENOUGH_DATA, in case there's
// script waiting for a "canplaythrough" event; without this forced
@ -3800,7 +3807,9 @@ HTMLMediaElement::UpdateReadyStateInternal()
if (NextFrameStatus() != MediaDecoderOwner::NEXT_FRAME_AVAILABLE) {
LOG(LogLevel::Debug, ("MediaElement %p UpdateReadyStateInternal() "
"Next frame not available", this));
ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA);
if (mFirstFrameLoaded) {
ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA);
}
if (!mWaitingFired && NextFrameStatus() == MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_BUFFERING) {
FireTimeUpdate(false);
DispatchAsyncEvent(NS_LITERAL_STRING("waiting"));
@ -3809,6 +3818,12 @@ HTMLMediaElement::UpdateReadyStateInternal()
return;
}
if (!mFirstFrameLoaded) {
// We haven't yet loaded the first frame, making us unable to determine
// if we have enough valid data at the present stage.
return;
}
if (mSrcStream) {
LOG(LogLevel::Debug, ("MediaElement %p UpdateReadyStateInternal() "
"Stream HAVE_ENOUGH_DATA", this));
@ -3824,8 +3839,7 @@ HTMLMediaElement::UpdateReadyStateInternal()
// autoplay elements for live streams will never play. Otherwise we
// move to HAVE_ENOUGH_DATA if we can play through the entire media
// without stopping to buffer.
if (mDecoder->CanPlayThrough())
{
if (mDecoder->CanPlayThrough()) {
LOG(LogLevel::Debug, ("MediaElement %p UpdateReadyStateInternal() "
"Decoder can play through", this));
ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA);

View File

@ -1513,6 +1513,9 @@ private:
// Indicates if user has interacted with the element.
// Used to block autoplay when disabled.
bool mHasUserInteraction;
// True if the first frame has been successfully loaded.
bool mFirstFrameLoaded;
};
} // namespace dom

View File

@ -35,6 +35,12 @@ class nsIPrincipal;
namespace mozilla {
#if DEUBG
#define LOG(args...) printf_stderr(args)
#else
#define LOG(...)
#endif
#ifdef MOZ_CHILD_PERMISSIONS
static bool
@ -118,11 +124,52 @@ AssertAppStatus(PBrowserParent* aActor,
return CheckAppStatusHelper(app, aStatus);
}
// A general purpose helper function to check permission against the origin
// rather than mozIApplication.
static bool
CheckOriginPermission(const nsACString& aOrigin, const char* aPermission)
{
LOG("CheckOriginPermission: %s, %s\n", nsCString(aOrigin).get(), aPermission);
nsIScriptSecurityManager *securityManager =
nsContentUtils::GetSecurityManager();
nsCOMPtr<nsIPrincipal> principal;
securityManager->CreateCodebasePrincipalFromOrigin(aOrigin,
getter_AddRefs(principal));
nsCOMPtr<nsIPermissionManager> permMgr = services::GetPermissionManager();
NS_ENSURE_TRUE(permMgr, false);
uint32_t perm;
nsresult rv = permMgr->TestExactPermissionFromPrincipal(principal, aPermission, &perm);
NS_ENSURE_SUCCESS(rv, false);
LOG("Permission %s for %s: %d\n", aPermission, nsCString(aOrigin).get(), perm);
return nsIPermissionManager::ALLOW_ACTION == perm;
}
bool
AssertAppProcess(TabContext& aContext,
AssertAppProcessType aType,
const char* aCapability)
{
const mozilla::OriginAttributes& attr = aContext.OriginAttributesRef();
nsCString suffix;
attr.CreateSuffix(suffix);
if (!aContext.SignedPkgOriginNoSuffix().IsEmpty()) {
LOG("TabContext owning signed package origin: %s, originAttr; %s\n",
nsCString(aContext.SignedPkgOriginNoSuffix()).get(),
suffix.get());
}
// Do a origin-based permission check if the TabContext owns a signed package.
if (!aContext.SignedPkgOriginNoSuffix().IsEmpty() &&
(ASSERT_APP_HAS_PERMISSION == aType || ASSERT_APP_PROCESS_PERMISSION == aType)) {
nsCString origin = aContext.SignedPkgOriginNoSuffix() + suffix;
return CheckOriginPermission(origin, aCapability);
}
nsCOMPtr<mozIApplication> app = aContext.GetOwnOrContainingApp();
return CheckAppTypeHelper(app, aType, aCapability, aContext.IsBrowserElement());

View File

@ -37,6 +37,11 @@ struct FrameIPCTabContext
// The ID of the app containing this app/browser frame, if applicable.
uint32_t frameOwnerAppId;
// The origin without originAttribute suffix for a signed package.
// This value would be empty if the TabContext doesn't own a signed
// package.
nsCString signedPkgOriginNoSuffix;
};
// IPCTabContext is an analog to mozilla::dom::TabContext. Both specify an

View File

@ -158,11 +158,17 @@ TabContext::OriginAttributesRef() const
return mOriginAttributes;
}
const nsACString&
TabContext::SignedPkgOriginNoSuffix() const
{
return mSignedPkgOriginNoSuffix;
}
bool
TabContext::SetTabContext(mozIApplication* aOwnApp,
mozIApplication* aAppFrameOwnerApp,
const OriginAttributes& aOriginAttributes)
const OriginAttributes& aOriginAttributes,
const nsACString& aSignedPkgOriginNoSuffix)
{
NS_ENSURE_FALSE(mInitialized, false);
@ -192,6 +198,7 @@ TabContext::SetTabContext(mozIApplication* aOwnApp,
mContainingAppId = containingAppId;
mOwnApp = aOwnApp;
mContainingApp = aAppFrameOwnerApp;
mSignedPkgOriginNoSuffix = aSignedPkgOriginNoSuffix;
return true;
}
@ -200,7 +207,9 @@ TabContext::AsIPCTabContext() const
{
nsAutoCString originSuffix;
mOriginAttributes.CreateSuffix(originSuffix);
return IPCTabContext(FrameIPCTabContext(originSuffix, mContainingAppId));
return IPCTabContext(FrameIPCTabContext(originSuffix,
mContainingAppId,
mSignedPkgOriginNoSuffix));
}
static already_AddRefed<mozIApplication>
@ -221,6 +230,7 @@ MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
uint32_t containingAppId = NO_APP_ID;
OriginAttributes originAttributes = OriginAttributes();
nsAutoCString originSuffix;
nsAutoCString signedPkgOriginNoSuffix;
const IPCTabContextUnion& contextUnion = aParams.contextUnion();
switch(contextUnion.type()) {
@ -276,6 +286,7 @@ MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
contextUnion.get_FrameIPCTabContext();
containingAppId = ipcContext.frameOwnerAppId();
signedPkgOriginNoSuffix = ipcContext.signedPkgOriginNoSuffix();
originSuffix = ipcContext.originSuffix();
originAttributes.PopulateFromSuffix(originSuffix);
break;
@ -305,7 +316,8 @@ MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
bool rv;
rv = mTabContext.SetTabContext(ownApp,
containingApp,
originAttributes);
originAttributes,
signedPkgOriginNoSuffix);
if (!rv) {
mInvalidReason = "Couldn't initialize TabContext.";
}

View File

@ -110,6 +110,12 @@ public:
*/
const OriginAttributes& OriginAttributesRef() const;
/**
* Returns the origin associated with the tab (w/o suffix) if this tab owns
* a signed packaged content.
*/
const nsACString& SignedPkgOriginNoSuffix() const;
protected:
friend class MaybeInvalidTabContext;
@ -136,7 +142,8 @@ protected:
*/
bool SetTabContext(mozIApplication* aOwnApp,
mozIApplication* aAppFrameOwnerApp,
const OriginAttributes& aOriginAttributes);
const OriginAttributes& aOriginAttributes,
const nsACString& aSignedPkgOriginNoSuffix);
private:
/**
@ -167,6 +174,13 @@ private:
*/
OriginAttributes mOriginAttributes;
/**
* The signed package origin without suffix. Since the signed packaged
* web content is always loaded in a separate process, it makes sense
* that we store this immutable value in TabContext. If the TabContext
* doesn't own a signed package, this value would be empty.
*/
nsCString mSignedPkgOriginNoSuffix;
};
/**
@ -184,11 +198,13 @@ public:
bool SetTabContext(mozIApplication* aOwnApp,
mozIApplication* aAppFrameOwnerApp,
const OriginAttributes& aOriginAttributes)
const OriginAttributes& aOriginAttributes,
const nsACString& aSignedPkgOriginNoSuffix = EmptyCString())
{
return TabContext::SetTabContext(aOwnApp,
aAppFrameOwnerApp,
aOriginAttributes);
aOriginAttributes,
aSignedPkgOriginNoSuffix);
}
};

View File

@ -518,7 +518,8 @@ TabParent::ShouldSwitchProcess(nsIChannel* aChannel)
}
void
TabParent::OnStartSignedPackageRequest(nsIChannel* aChannel)
TabParent::OnStartSignedPackageRequest(nsIChannel* aChannel,
const nsACString& aPackageId)
{
if (!ShouldSwitchProcess(aChannel)) {
return;
@ -537,7 +538,7 @@ TabParent::OnStartSignedPackageRequest(nsIChannel* aChannel)
RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
NS_ENSURE_TRUE_VOID(frameLoader);
nsresult rv = frameLoader->SwitchProcessAndLoadURI(uri);
nsresult rv = frameLoader->SwitchProcessAndLoadURI(uri, aPackageId);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to switch process.");
}

View File

@ -456,7 +456,8 @@ public:
// Called by HttpChannelParent. The function may use a new process to
// reload the URI associated with the given channel.
void OnStartSignedPackageRequest(nsIChannel* aChannel);
void OnStartSignedPackageRequest(nsIChannel* aChannel,
const nsACString& aPackageId);
protected:
bool ReceiveMessage(const nsString& aMessage,

View File

@ -36,108 +36,66 @@ using namespace mozilla::layers;
const TrackID TRACK_VIDEO_PRIMARY = 1;
/**
* TrackPort is a representation of a MediaStreamTrack-MediaInputPort pair
* that make up a link between the Owned stream and the Playback stream.
*
* Semantically, the track is the identifier/key and the port the value of this
* connection.
*
* The input port can be shared between several TrackPorts. This is the case
* for DOMMediaStream's mPlaybackPort which forwards all tracks in its
* mOwnedStream automatically.
*
* If the MediaStreamTrack is owned by another DOMMediaStream (called A) than
* the one owning the TrackPort (called B), the input port (locked to the
* MediaStreamTrack's TrackID) connects A's mOwnedStream to B's mPlaybackStream.
*
* A TrackPort may never leave the DOMMediaStream it was created in. Internal
* use only.
*/
class DOMMediaStream::TrackPort
DOMMediaStream::TrackPort::TrackPort(MediaInputPort* aInputPort,
MediaStreamTrack* aTrack,
const InputPortOwnership aOwnership)
: mInputPort(aInputPort)
, mTrack(aTrack)
, mOwnership(aOwnership)
{
public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(TrackPort)
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(TrackPort)
// XXX Bug 1124630. nsDOMCameraControl requires adding a track without and
// input port.
// MOZ_ASSERT(mInputPort);
MOZ_ASSERT(mTrack);
enum class InputPortOwnership {
OWNED = 1,
EXTERNAL
};
MOZ_COUNT_CTOR(TrackPort);
}
TrackPort(MediaInputPort* aInputPort,
MediaStreamTrack* aTrack,
const InputPortOwnership aOwnership)
: mInputPort(aInputPort)
, mTrack(aTrack)
, mOwnership(aOwnership)
{
MOZ_ASSERT(mInputPort);
MOZ_ASSERT(mTrack);
DOMMediaStream::TrackPort::~TrackPort()
{
MOZ_COUNT_DTOR(TrackPort);
MOZ_COUNT_CTOR(TrackPort);
if (mOwnership == InputPortOwnership::OWNED && mInputPort) {
mInputPort->Destroy();
mInputPort = nullptr;
}
}
protected:
virtual ~TrackPort()
{
MOZ_COUNT_DTOR(TrackPort);
if (mOwnership == InputPortOwnership::OWNED && mInputPort) {
mInputPort->Destroy();
mInputPort = nullptr;
}
void
DOMMediaStream::TrackPort::DestroyInputPort()
{
if (mInputPort) {
mInputPort->Destroy();
mInputPort = nullptr;
}
}
public:
void DestroyInputPort()
{
if (mInputPort) {
mInputPort->Destroy();
mInputPort = nullptr;
}
MediaStream*
DOMMediaStream::TrackPort::GetSource() const
{
return mInputPort ? mInputPort->GetSource() : nullptr;
}
TrackID
DOMMediaStream::TrackPort::GetSourceTrackId() const
{
return mInputPort ? mInputPort->GetSourceTrackId() : TRACK_INVALID;
}
void
DOMMediaStream::TrackPort::BlockTrackId(TrackID aTrackId)
{
if (mInputPort) {
mInputPort->BlockTrackId(aTrackId);
}
/**
* Returns the source stream of the input port.
*/
MediaStream* GetSource() const { return mInputPort ? mInputPort->GetSource()
: nullptr; }
/**
* Returns the track ID this track is locked to in the source stream of the
* input port.
*/
TrackID GetSourceTrackId() const { return mInputPort ? mInputPort->GetSourceTrackId()
: TRACK_INVALID; }
MediaInputPort* GetInputPort() const { return mInputPort; }
MediaStreamTrack* GetTrack() const { return mTrack; }
/**
* Blocks aTrackId from going into mInputPort unless the port has been
* destroyed.
*/
void BlockTrackId(TrackID aTrackId)
{
if (mInputPort) {
mInputPort->BlockTrackId(aTrackId);
}
}
private:
RefPtr<MediaInputPort> mInputPort;
RefPtr<MediaStreamTrack> mTrack;
// Defines if we've been given ownership of the input port or if it's owned
// externally. The owner is responsible for destroying the port.
const InputPortOwnership mOwnership;
};
}
NS_IMPL_CYCLE_COLLECTION(DOMMediaStream::TrackPort, mTrack)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMMediaStream::TrackPort, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMMediaStream::TrackPort, Release)
/**
* Listener registered on the Owned stream to detect added and ended owned
* tracks for keeping the list of MediaStreamTracks in sync with the tracks

View File

@ -173,7 +173,6 @@ class MediaStreamDirectListener;
*/
class DOMMediaStream : public DOMEventTargetHelper
{
class TrackPort;
friend class DOMLocalMediaStream;
typedef dom::MediaStreamTrack MediaStreamTrack;
typedef dom::AudioStreamTrack AudioStreamTrack;
@ -208,7 +207,83 @@ public:
virtual ~TrackListener() {}
};
DOMMediaStream();
/**
* TrackPort is a representation of a MediaStreamTrack-MediaInputPort pair
* that make up a link between the Owned stream and the Playback stream.
*
* Semantically, the track is the identifier/key and the port the value of this
* connection.
*
* The input port can be shared between several TrackPorts. This is the case
* for DOMMediaStream's mPlaybackPort which forwards all tracks in its
* mOwnedStream automatically.
*
* If the MediaStreamTrack is owned by another DOMMediaStream (called A) than
* the one owning the TrackPort (called B), the input port (locked to the
* MediaStreamTrack's TrackID) connects A's mOwnedStream to B's mPlaybackStream.
*
* A TrackPort may never leave the DOMMediaStream it was created in. Internal
* use only.
*/
class TrackPort
{
public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(TrackPort)
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(TrackPort)
/**
* Indicates MediaInputPort ownership to the TrackPort.
*
* OWNED - Owned by the TrackPort itself. TrackPort must destroy the
* input port when it's destructed.
* EXTERNAL - Owned by another entity. It's the caller's responsibility to
* ensure the the MediaInputPort outlives the TrackPort.
*/
enum class InputPortOwnership {
OWNED = 1,
EXTERNAL
};
TrackPort(MediaInputPort* aInputPort,
MediaStreamTrack* aTrack,
const InputPortOwnership aOwnership);
protected:
virtual ~TrackPort();
public:
void DestroyInputPort();
/**
* Returns the source stream of the input port.
*/
MediaStream* GetSource() const;
/**
* Returns the track ID this track is locked to in the source stream of the
* input port.
*/
TrackID GetSourceTrackId() const;
MediaInputPort* GetInputPort() const { return mInputPort; }
MediaStreamTrack* GetTrack() const { return mTrack; }
/**
* Blocks aTrackId from going into mInputPort unless the port has been
* destroyed.
*/
void BlockTrackId(TrackID aTrackId);
private:
RefPtr<MediaInputPort> mInputPort;
RefPtr<MediaStreamTrack> mTrack;
// Defines if we've been given ownership of the input port or if it's owned
// externally. The owner is responsible for destroying the port.
const InputPortOwnership mOwnership;
};
DOMMediaStream();
NS_DECL_ISUPPORTS_INHERITED
NS_REALLY_FORWARD_NSIDOMEVENTTARGET(DOMEventTargetHelper)

View File

@ -1246,6 +1246,18 @@ MediaDecoderStateMachine::SetDormant(bool aDormant)
return;
}
if (mMetadataRequest.Exists()) {
if (mPendingDormant && mPendingDormant.ref() != aDormant && !aDormant) {
// We already have a dormant request pending; the new request would have
// resumed from dormant, we can just cancel any pending dormant requests.
mPendingDormant.reset();
} else {
mPendingDormant = Some(aDormant);
}
return;
}
mPendingDormant.reset();
DECODER_LOG("SetDormant=%d", aDormant);
if (aDormant) {
@ -1906,6 +1918,11 @@ MediaDecoderStateMachine::OnMetadataRead(MetadataHolder* aMetadata)
MOZ_ASSERT(mState == DECODER_STATE_DECODING_METADATA);
mMetadataRequest.Complete();
if (mPendingDormant) {
SetDormant(mPendingDormant.ref());
return;
}
// Set mode to PLAYBACK after reading metadata.
mResource->SetReadMode(MediaCacheStream::MODE_PLAYBACK);
mDecoder->DispatchSetMediaSeekable(mReader->IsMediaSeekable());

View File

@ -1086,6 +1086,9 @@ private:
// been written to the MediaStream.
Watchable<bool> mAudioCompleted;
// Set if MDSM receives dormant request during reading metadata.
Maybe<bool> mPendingDormant;
// Flag whether we notify metadata before decoding the first frame or after.
//
// Note that the odd semantics here are designed to replicate the current

View File

@ -92,7 +92,6 @@ MediaFormatReader::Shutdown()
MOZ_ASSERT(OnTaskQueue());
mDemuxerInitRequest.DisconnectIfExists();
mDecodersInitRequest.DisconnectIfExists();
mMetadataPromise.RejectIfExists(ReadMetadataFailureReason::METADATA_ERROR, __func__);
mSeekPromise.RejectIfExists(NS_ERROR_FAILURE, __func__);
mSkipRequest.DisconnectIfExists();
@ -102,6 +101,7 @@ MediaFormatReader::Shutdown()
if (mAudio.HasPromise()) {
mAudio.RejectPromise(CANCELED, __func__);
}
mAudio.mInitPromise.DisconnectIfExists();
mAudio.mDecoder->Shutdown();
mAudio.mDecoder = nullptr;
}
@ -122,6 +122,7 @@ MediaFormatReader::Shutdown()
if (mVideo.HasPromise()) {
mVideo.RejectPromise(CANCELED, __func__);
}
mVideo.mInitPromise.DisconnectIfExists();
mVideo.mDecoder->Shutdown();
mVideo.mDecoder = nullptr;
}
@ -248,24 +249,18 @@ MediaFormatReader::AsyncReadMetadata()
{
MOZ_ASSERT(OnTaskQueue());
RefPtr<MetadataPromise> p = mMetadataPromise.Ensure(__func__);
MOZ_DIAGNOSTIC_ASSERT(mMetadataPromise.IsEmpty());
if (mInitDone) {
// We are returning from dormant.
if (!EnsureDecodersCreated()) {
mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
return p;
}
MOZ_ASSERT(!mDecodersInitRequest.Exists());
if (EnsureDecodersInitialized()) {
RefPtr<MetadataHolder> metadata = new MetadataHolder();
metadata->mInfo = mInfo;
metadata->mTags = nullptr;
mMetadataPromise.Resolve(metadata, __func__);
}
return p;
RefPtr<MetadataHolder> metadata = new MetadataHolder();
metadata->mInfo = mInfo;
metadata->mTags = nullptr;
return MetadataPromise::CreateAndResolve(metadata, __func__);
}
RefPtr<MetadataPromise> p = mMetadataPromise.Ensure(__func__);
mDemuxerInitRequest.Begin(mDemuxer->Init()
->Then(OwnerThread(), __func__, this,
&MediaFormatReader::OnDemuxerInitDone,
@ -341,24 +336,11 @@ MediaFormatReader::OnDemuxerInitDone(nsresult)
return;
}
if (IsWaitingOnCDMResource()) {
// Decoder can't be allocated before CDM resource is ready, so resolving the
// mMetadataPromise here to wait for CDM on MDSM.
mInitDone = true;
RefPtr<MetadataHolder> metadata = new MetadataHolder();
metadata->mInfo = mInfo;
metadata->mTags = nullptr;
mMetadataPromise.Resolve(metadata, __func__);
return;
}
if (!EnsureDecodersCreated()) {
mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
return;
}
MOZ_ASSERT(!mDecodersInitRequest.Exists());
EnsureDecodersInitialized();
mInitDone = true;
RefPtr<MetadataHolder> metadata = new MetadataHolder();
metadata->mInfo = mInfo;
metadata->mTags = nullptr;
mMetadataPromise.Resolve(metadata, __func__);
}
void
@ -447,81 +429,6 @@ MediaFormatReader::EnsureDecoderInitialized(TrackType aTrack)
return false;
}
bool
MediaFormatReader::EnsureDecodersInitialized()
{
MOZ_ASSERT(OnTaskQueue());
MOZ_ASSERT(mVideo.mDecoder || mAudio.mDecoder);
// DecodeDemuxedSample() could call this function before mDecodersInitRequest
// is completed. And it is ok to return false here because DecodeDemuxedSample
// will call ScheduleUpdate() again.
// It also avoids calling decoder->Init() multiple times.
if (mDecodersInitRequest.Exists()) {
MOZ_ASSERT(false);
return false;
}
nsTArray<RefPtr<MediaDataDecoder::InitPromise>> promises;
if (mVideo.mDecoder && !mVideo.mDecoderInitialized) {
MOZ_ASSERT(!mVideo.mInitPromise.Exists());
promises.AppendElement(mVideo.mDecoder->Init());
}
if (mAudio.mDecoder && !mAudio.mDecoderInitialized) {
MOZ_ASSERT(!mAudio.mInitPromise.Exists());
promises.AppendElement(mAudio.mDecoder->Init());
}
if (promises.Length()) {
mDecodersInitRequest.Begin(MediaDataDecoder::InitPromise::All(OwnerThread(), promises)
->Then(OwnerThread(), __func__, this,
&MediaFormatReader::OnDecoderInitDone,
&MediaFormatReader::OnDecoderInitFailed));
}
LOG("Init decoders: audio: %p, audio init: %d, video: %p, video init: %d",
mAudio.mDecoder.get(), mAudio.mDecoderInitialized,
mVideo.mDecoder.get(), mVideo.mDecoderInitialized);
// Return false if any decoder is under initialization.
return !promises.Length();
}
void
MediaFormatReader::OnDecoderInitDone(const nsTArray<TrackType>& aTrackTypes)
{
MOZ_ASSERT(OnTaskQueue());
mDecodersInitRequest.Complete();
for (const auto& track : aTrackTypes) {
auto& decoder = GetDecoderData(track);
decoder.mDecoderInitialized = true;
}
MOZ_ASSERT(!mMetadataPromise.IsEmpty());
mInitDone = true;
RefPtr<MetadataHolder> metadata = new MetadataHolder();
metadata->mInfo = mInfo;
metadata->mTags = nullptr;
mMetadataPromise.Resolve(metadata, __func__);
}
void
MediaFormatReader::OnDecoderInitFailed(MediaDataDecoder::DecoderFailureReason aReason)
{
MOZ_ASSERT(OnTaskQueue());
mDecodersInitRequest.Complete();
NS_WARNING("Failed to init decoder");
mMetadataPromise.RejectIfExists(ReadMetadataFailureReason::METADATA_ERROR, __func__);
NotifyError(TrackType::kAudioTrack);
NotifyError(TrackType::kVideoTrack);
}
void
MediaFormatReader::ReadUpdatedMetadata(MediaInfo* aInfo)
{
@ -1614,6 +1521,7 @@ void MediaFormatReader::ReleaseMediaResources()
mVideoFrameContainer->ClearCurrentFrame();
}
if (mVideo.mDecoder) {
mVideo.mInitPromise.DisconnectIfExists();
mVideo.mDecoder->Shutdown();
mVideo.mDecoder = nullptr;
}

View File

@ -123,9 +123,6 @@ private:
void ReturnOutput(MediaData* aData, TrackType aTrack);
bool EnsureDecodersCreated();
// It returns true when all decoders are initialized. False when there is pending
// initialization.
bool EnsureDecodersInitialized();
bool EnsureDecoderInitialized(TrackType aTrack);
// Enqueues a task to call Update(aTrack) on the decoder task queue.
@ -368,9 +365,6 @@ private:
DecoderData& GetDecoderData(TrackType aTrack);
void OnDecoderInitDone(const nsTArray<TrackType>& aTrackTypes);
void OnDecoderInitFailed(MediaDataDecoder::DecoderFailureReason aReason);
// Demuxer objects.
RefPtr<MediaDataDemuxer> mDemuxer;
bool mDemuxerInitDone;
@ -449,9 +443,6 @@ private:
Maybe<media::TimeUnit> mPendingSeekTime;
MozPromiseHolder<SeekPromise> mSeekPromise;
// Pending decoders initialization.
MozPromiseRequestHolder<MediaDataDecoder::InitPromise::AllPromiseType> mDecodersInitRequest;
RefPtr<VideoFrameContainer> mVideoFrameContainer;
layers::ImageContainer* GetImageContainer();

View File

@ -22,7 +22,7 @@ function startTest(test, token) {
ok(false, test.name + " should not fire '" + type + "' event");
}};
var events = [
'loadedmetadata', 'load',
'loadeddata', 'load',
'canplay', 'canplaythrough',
'playing'
];

View File

@ -1,6 +1,6 @@
load 351236-1.html
load 407062-1.html
load 419563-1.xhtml
skip-if(winWidget) load 428844-1.html # bug 471185
load 428844-1.html
load 461049-1.html
asserts(0-1) asserts-if(winWidget||Android,0-2) load removing-editable-xslt.html # bug 500847

View File

@ -1100,7 +1100,7 @@ DrawTargetCairo::ClearRect(const Rect& aRect)
if (!mContext || aRect.Width() <= 0 || aRect.Height() <= 0 ||
!IsFinite(aRect.X()) || !IsFinite(aRect.Width()) ||
!IsFinite(aRect.Y()) || !IsFinite(aRect.Height())) {
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "ClearRect with invalid argument " << gfx::hexa(mContext) << " with " << aRect.Width() << "x" << aRect.Height() << " [" << aRect.X() << ", " << aRect.Y() << "]";
gfxCriticalNote << "ClearRect with invalid argument " << gfx::hexa(mContext) << " with " << aRect.Width() << "x" << aRect.Height() << " [" << aRect.X() << ", " << aRect.Y() << "]";
}
cairo_set_antialias(mContext, CAIRO_ANTIALIAS_NONE);

View File

@ -140,7 +140,7 @@ public:
RefPtr<ID2D1BitmapBrush> brush;
HRESULT hr = rt->CreateBitmapBrush(mOldSurfBitmap, D2D1::BitmapBrushProperties(), D2D1::BrushProperties(), getter_AddRefs(brush));
if (FAILED(hr)) {
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "[D2D] CreateBitmapBrush failure " << hexa(hr);
gfxCriticalNote << "[D2D] CreateBitmapBrush failure " << hexa(hr);
return;
}

View File

@ -905,7 +905,7 @@ DrawTargetD2D1::Init(const IntSize &aSize, SurfaceFormat aFormat)
if (mDC->GetMaximumBitmapSize() < UINT32(aSize.width) ||
mDC->GetMaximumBitmapSize() < UINT32(aSize.height)) {
// This is 'ok', so don't assert
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "[D2D1.1] Attempt to use unsupported surface size " << aSize;
gfxCriticalNote << "[D2D1.1] Attempt to use unsupported surface size " << aSize;
return false;
}

View File

@ -0,0 +1,28 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GFX_LAYERUSERDATA_H
#define GFX_LAYERUSERDATA_H
namespace mozilla {
namespace layers {
/**
* Base class for userdata objects attached to layers and layer managers.
*
* We define it here in a separate header so clients only need to include
* this header for their class definitions, rather than pulling in Layers.h.
* Everything else in Layers.h should be forward-declarable.
*/
class LayerUserData {
public:
virtual ~LayerUserData() {}
};
} // namespace layers
} // namespace mozilla
#endif /* GFX_LAYERUSERDATA_H */

View File

@ -205,6 +205,19 @@ LayerManager::AreComponentAlphaLayersEnabled()
return gfxPrefs::ComponentAlphaEnabled();
}
/*static*/ void
LayerManager::LayerUserDataDestroy(void* data)
{
delete static_cast<LayerUserData*>(data);
}
nsAutoPtr<LayerUserData>
LayerManager::RemoveUserData(void* aKey)
{
nsAutoPtr<LayerUserData> d(static_cast<LayerUserData*>(mUserData.Remove(static_cast<gfx::UserDataKey*>(aKey))));
return d;
}
//--------------------------------------------------
// Layer
@ -2058,6 +2071,13 @@ Layer::IsBackfaceHidden()
return false;
}
nsAutoPtr<LayerUserData>
Layer::RemoveUserData(void* aKey)
{
nsAutoPtr<LayerUserData> d(static_cast<LayerUserData*>(mUserData.Remove(static_cast<gfx::UserDataKey*>(aKey))));
return d;
}
void
PaintedLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
{

View File

@ -103,13 +103,8 @@ class LayersPacket;
virtual const char* Name() const override { return n; } \
virtual LayerType GetType() const override { return e; }
/**
* Base class for userdata objects attached to layers and layer managers.
*/
class LayerUserData {
public:
virtual ~LayerUserData() {}
};
// Defined in LayerUserData.h; please include that file instead.
class LayerUserData;
/*
* Motivation: For truly smooth animation and video playback, we need to
@ -137,11 +132,6 @@ public:
* BasicLayerManager for such an implementation.
*/
static void LayerManagerUserDataDestroy(void *data)
{
delete static_cast<LayerUserData*>(data);
}
/**
* A LayerManager controls a tree of layers. All layers in the tree
* must use the same LayerManager.
@ -509,16 +499,13 @@ public:
*/
void SetUserData(void* aKey, LayerUserData* aData)
{
mUserData.Add(static_cast<gfx::UserDataKey*>(aKey), aData, LayerManagerUserDataDestroy);
mUserData.Add(static_cast<gfx::UserDataKey*>(aKey), aData, LayerUserDataDestroy);
}
/**
* This can be used anytime. Ownership passes to the caller!
*/
nsAutoPtr<LayerUserData> RemoveUserData(void* aKey)
{
nsAutoPtr<LayerUserData> d(static_cast<LayerUserData*>(mUserData.Remove(static_cast<gfx::UserDataKey*>(aKey))));
return d;
}
nsAutoPtr<LayerUserData> RemoveUserData(void* aKey);
/**
* This getter can be used anytime.
*/
@ -676,6 +663,8 @@ public:
return false;
}
static void LayerUserDataDestroy(void* data);
protected:
RefPtr<Layer> mRoot;
gfx::UserData mUserData;
@ -1389,16 +1378,12 @@ public:
*/
void SetUserData(void* aKey, LayerUserData* aData)
{
mUserData.Add(static_cast<gfx::UserDataKey*>(aKey), aData, LayerManagerUserDataDestroy);
mUserData.Add(static_cast<gfx::UserDataKey*>(aKey), aData, LayerManager::LayerUserDataDestroy);
}
/**
* This can be used anytime. Ownership passes to the caller!
*/
nsAutoPtr<LayerUserData> RemoveUserData(void* aKey)
{
nsAutoPtr<LayerUserData> d(static_cast<LayerUserData*>(mUserData.Remove(static_cast<gfx::UserDataKey*>(aKey))));
return d;
}
nsAutoPtr<LayerUserData> RemoveUserData(void* aKey);
/**
* This getter can be used anytime.
*/
@ -1472,10 +1457,13 @@ public:
bool Extend3DContext() {
return GetContentFlags() & CONTENT_EXTEND_3D_CONTEXT;
}
bool Is3DContextLeaf() {
return !Extend3DContext() && GetParent() &&
bool Combines3DTransformWithAncestors() {
return GetParent() &&
reinterpret_cast<Layer*>(GetParent())->Extend3DContext();
}
bool Is3DContextLeaf() {
return !Extend3DContext() && Combines3DTransformWithAncestors();
}
/**
* It is true if the user can see the back of the layer and the
* backface is hidden. The compositor should skip the layer if the

View File

@ -864,6 +864,10 @@ InstallLayerClipPreserves3D(gfxContext* aTarget, Layer* aLayer)
if (!clipRect) {
return;
}
MOZ_ASSERT(!aLayer->Extend3DContext() ||
!aLayer->Combines3DTransformWithAncestors(),
"Layers in a preserve 3D context have no clip"
" except leaves and the estabisher!");
Layer* parent = aLayer->GetParent();
Matrix4x4 transform3d =

View File

@ -135,8 +135,7 @@ private:
if (SUCCEEDED(hr))
return false;
gfxCriticalError(CriticalLog::DefaultOptions(false))
<< "[D3D11] " << aContext << " failed: " << hexa(hr);
gfxCriticalNote << "[D3D11] " << aContext << " failed: " << hexa(hr);
return true;
}
@ -198,8 +197,7 @@ CompositorD3D11::Initialize()
mDevice->GetImmediateContext(getter_AddRefs(mContext));
if (!mContext) {
gfxCriticalError(CriticalLog::DefaultOptions(false))
<< "[D3D11] failed to get immediate context";
gfxCriticalNote << "[D3D11] failed to get immediate context";
return false;
}
@ -485,7 +483,7 @@ CompositorD3D11::CreateRenderTarget(const gfx::IntRect& aRect,
RefPtr<ID3D11Texture2D> texture;
HRESULT hr = mDevice->CreateTexture2D(&desc, nullptr, getter_AddRefs(texture));
if (Failed(hr) || !texture) {
gfxCriticalError(gfxCriticalError::DefaultOptions(false)) << "Failed in CreateRenderTarget";
gfxCriticalNote << "Failed in CreateRenderTarget " << hexa(hr);
return nullptr;
}
@ -519,7 +517,7 @@ CompositorD3D11::CreateRenderTargetFromSource(const gfx::IntRect &aRect,
HRESULT hr = mDevice->CreateTexture2D(&desc, nullptr, getter_AddRefs(texture));
NS_ASSERTION(texture, "Could not create texture");
if (Failed(hr) || !texture) {
gfxCriticalError(gfxCriticalError::DefaultOptions(false)) << "Failed in CreateRenderTargetFromSource";
gfxCriticalNote << "Failed in CreateRenderTargetFromSource " << hexa(hr);
return nullptr;
}
@ -1235,7 +1233,7 @@ CompositorD3D11::UpdateRenderTarget()
{
EnsureSize();
if (!VerifyBufferSize()) {
gfxCriticalError(gfxCriticalError::DefaultOptions(false)) << "Failed VerifyBufferSize in UpdateRenderTarget " << mSize;
gfxCriticalNote << "Failed VerifyBufferSize in UpdateRenderTarget " << mSize;
return;
}
@ -1244,7 +1242,7 @@ CompositorD3D11::UpdateRenderTarget()
}
if (mSize.width <= 0 || mSize.height <= 0) {
gfxCriticalError(gfxCriticalError::DefaultOptions(false)) << "Invalid size in UpdateRenderTarget " << mSize;
gfxCriticalNote << "Invalid size in UpdateRenderTarget " << mSize;
return;
}
@ -1261,7 +1259,7 @@ CompositorD3D11::UpdateRenderTarget()
}
}
if (Failed(hr)) {
gfxCriticalError(gfxCriticalError::DefaultOptions(false)) << "Failed in UpdateRenderTarget";
gfxCriticalNote << "Failed in UpdateRenderTarget " << hexa(hr);
return;
}
@ -1444,8 +1442,7 @@ CompositorD3D11::Failed(HRESULT hr, const char* aContext)
if (SUCCEEDED(hr))
return false;
gfxCriticalError(CriticalLog::DefaultOptions(false))
<< "[D3D11] " << aContext << " failed: " << hexa(hr);
gfxCriticalNote << "[D3D11] " << aContext << " failed: " << hexa(hr);
return true;
}

View File

@ -75,7 +75,7 @@ TextureSourceD3D11::GetShaderResourceView()
mTexture->GetDevice(getter_AddRefs(device));
HRESULT hr = device->CreateShaderResourceView(mTexture, nullptr, getter_AddRefs(mSRV));
if (FAILED(hr)) {
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "[D3D11] TextureSourceD3D11:GetShaderResourceView CreateSRV failure " << gfx::hexa(hr);
gfxCriticalNote << "[D3D11] TextureSourceD3D11:GetShaderResourceView CreateSRV failure " << gfx::hexa(hr);
return nullptr;
}
}
@ -1129,7 +1129,7 @@ DataTextureSourceD3D11::GetShaderResourceView()
mTileTextures[mCurrentTile]->GetDevice(getter_AddRefs(device));
HRESULT hr = device->CreateShaderResourceView(mTileTextures[mCurrentTile], nullptr, getter_AddRefs(mTileSRVs[mCurrentTile]));
if (FAILED(hr)) {
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "[D3D11] DataTextureSourceD3D11:GetShaderResourceView CreateSRV failure " << gfx::hexa(hr);
gfxCriticalNote << "[D3D11] DataTextureSourceD3D11:GetShaderResourceView CreateSRV failure " << gfx::hexa(hr);
return nullptr;
}
}

View File

@ -37,6 +37,7 @@ EXPORTS += [
'LayerSorter.h',
'LayersTypes.h',
'LayerTreeInvalidation.h',
'LayerUserData.h',
'opengl/Composer2D.h',
'opengl/OGLShaderProgram.h',
'opengl/TexturePoolOGL.h',

View File

@ -424,14 +424,14 @@ void
D3D11LayersCrashGuard::LogCrashRecovery()
{
RecordTelemetry(TelemetryState::RecoveredFromCrash);
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "D3D11 layers just crashed; D3D11 will be disabled.";
gfxCriticalNote << "D3D11 layers just crashed; D3D11 will be disabled.";
}
void
D3D11LayersCrashGuard::LogFeatureDisabled()
{
RecordTelemetry(TelemetryState::FeatureDisabled);
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "D3D11 layers disabled due to a prior crash.";
gfxCriticalNote << "D3D11 layers disabled due to a prior crash.";
}
void
@ -468,13 +468,13 @@ D3D9VideoCrashGuard::UpdateEnvironment()
void
D3D9VideoCrashGuard::LogCrashRecovery()
{
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "DXVA2D3D9 just crashed; hardware video will be disabled.";
gfxCriticalNote << "DXVA2D3D9 just crashed; hardware video will be disabled.";
}
void
D3D9VideoCrashGuard::LogFeatureDisabled()
{
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "DXVA2D3D9 video decoding is disabled due to a previous crash.";
gfxCriticalNote << "DXVA2D3D9 video decoding is disabled due to a previous crash.";
}
GLContextCrashGuard::GLContextCrashGuard(dom::ContentParent* aContentParent)
@ -525,13 +525,13 @@ GLContextCrashGuard::UpdateEnvironment()
void
GLContextCrashGuard::LogCrashRecovery()
{
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "GLContext just crashed and is now disabled.";
gfxCriticalNote << "GLContext just crashed and is now disabled.";
}
void
GLContextCrashGuard::LogFeatureDisabled()
{
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "GLContext is disabled due to a previous crash.";
gfxCriticalNote << "GLContext is disabled due to a previous crash.";
}
} // namespace gfx

View File

@ -255,8 +255,7 @@
#define NS_THEME_WIN_MEDIA_TOOLBOX 222
#define NS_THEME_WIN_BROWSER_TAB_BAR_TOOLBOX 223
// Unified toolbar and titlebar elements on the Mac
#define NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR 224
// Titlebar elements on the Mac
#define NS_THEME_MOZ_MAC_FULLSCREEN_BUTTON 226
// Mac help button

View File

@ -6,6 +6,7 @@
#include "TestLayers.h"
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "LayerUserData.h"
#include "mozilla/layers/LayerMetricsWrapper.h"
#include "mozilla/layers/CompositorParent.h"

View File

@ -1912,7 +1912,7 @@ bool DoesD3D11TextureSharingWorkInternal(ID3D11Device *device, DXGI_FORMAT forma
// This if(FAILED()) is the one that actually fails on systems affected by bug 1083071.
if (FAILED(device->CreateShaderResourceView(sharedTexture, NULL, getter_AddRefs(sharedView)))) {
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "CreateShaderResourceView failed for format" << format;
gfxCriticalNote << "CreateShaderResourceView failed for format" << format;
return false;
}

View File

@ -31,7 +31,7 @@ gfxWindowsSurface::gfxWindowsSurface(HDC dc, uint32_t flags) :
Init(cairo_win32_printing_surface_create(mDC));
mForPrinting = true;
if (!mSurfaceValid) {
gfxCriticalError(gfxCriticalError::DefaultOptions(false)) << "Invalid printing surface";
gfxCriticalNote << "Invalid printing surface";
}
} else
#endif

View File

@ -27,7 +27,12 @@ class AsyncNotifyRunnable;
class AsyncNotifyCurrentStateRunnable;
class Image;
// Image progress bitflags.
/**
* Image progress bitflags.
*
* See CheckProgressConsistency() for the invariants we enforce about the
* ordering dependencies betweeen these flags.
*/
enum {
FLAG_SIZE_AVAILABLE = 1u << 0, // STATUS_SIZE_AVAILABLE
FLAG_DECODE_COMPLETE = 1u << 1, // STATUS_DECODE_COMPLETE

View File

@ -1225,9 +1225,7 @@ VectorImage::OnSVGDocumentError()
if (mProgressTracker) {
// Notify observers about the error and unblock page load.
Progress progress = FLAG_DECODE_COMPLETE |
FLAG_ONLOAD_UNBLOCKED |
FLAG_HAS_ERROR;
Progress progress = FLAG_ONLOAD_UNBLOCKED | FLAG_HAS_ERROR;
// Merge in any saved progress from OnImageDataComplete.
if (mLoadProgress) {

View File

@ -76,7 +76,7 @@ bool TestManyChildAllocsChild::RecvGo()
fail("can't send Hello()");
}
size_t len = ManagedPTestManyChildAllocsSubChild().Length();
size_t len = ManagedPTestManyChildAllocsSubChild().Count();
if (NALLOCS != len)
fail("expected %lu kids, got %lu", NALLOCS, len);

View File

@ -1,6 +1,7 @@
#include "TestMultiMgrs.h"
#include "IPDLUnitTests.h" // fail etc.
#include "mozilla/ipc/ProtocolUtils.h"
namespace mozilla {
namespace _ipdltest {
@ -70,17 +71,17 @@ TestMultiMgrsRightChild::RecvPTestMultiMgrsBottomConstructor(
bool
TestMultiMgrsChild::RecvCheck()
{
if (1 != ManagedPTestMultiMgrsLeftChild().Length())
if (1 != ManagedPTestMultiMgrsLeftChild().Count())
fail("where's leftie?");
if (1 != ManagedPTestMultiMgrsRightChild().Length())
if (1 != ManagedPTestMultiMgrsRightChild().Count())
fail("where's rightie?");
TestMultiMgrsLeftChild* leftie =
static_cast<TestMultiMgrsLeftChild*>(
ManagedPTestMultiMgrsLeftChild()[0]);
LoneManagedOrNull(ManagedPTestMultiMgrsLeftChild()));
TestMultiMgrsRightChild* rightie =
static_cast<TestMultiMgrsRightChild*>(
ManagedPTestMultiMgrsRightChild()[0]);
LoneManagedOrNull(ManagedPTestMultiMgrsRightChild()));
if (!leftie->HasChild(mBottomL))
fail("leftie didn't have a child it was supposed to!");

View File

@ -230,7 +230,7 @@ ValidateArrayView(JSContext* cx, AsmJSModule::Global& global, HandleValue global
bool tac = IsTypedArrayConstructor(v, global.viewType());
bool stac = IsSharedTypedArrayConstructor(v, global.viewType());
if (!((tac || stac) && stac == isShared))
if (!(tac || (stac && isShared)))
return LinkFail(cx, "bad typed array constructor");
return true;

View File

@ -314,6 +314,10 @@ class AsmJSModule
MOZ_ASSERT(pod.which_ == ArrayView || pod.which_ == SharedArrayView || pod.which_ == ArrayViewCtor);
return pod.u.viewType_;
}
void makeViewShared() {
MOZ_ASSERT(pod.which_ == ArrayView);
pod.which_ = SharedArrayView;
}
PropertyName* mathName() const {
MOZ_ASSERT(pod.which_ == MathBuiltinFunction);
return name_;
@ -1106,6 +1110,15 @@ class AsmJSModule
return pod.isSharedView_ == shared;
return !pod.isSharedView_ || shared;
}
void setViewsAreShared() {
if (pod.hasArrayView_)
pod.isSharedView_ = true;
for (size_t i=0 ; i < globals_.length() ; i++) {
Global& g = globals_[i];
if (g.which() == Global::ArrayView)
g.makeViewShared();
}
}
/*************************************************************************/

View File

@ -773,6 +773,10 @@ class MOZ_STACK_CLASS ModuleValidator
MOZ_ASSERT(isAnyArrayView());
return u.viewInfo.isSharedView_;
}
void setViewIsSharedView() {
MOZ_ASSERT(isAnyArrayView());
u.viewInfo.isSharedView_ = true;
}
bool isMathFunction() const {
return which_ == MathBuiltinFunction;
}
@ -918,6 +922,7 @@ class MOZ_STACK_CLASS ModuleValidator
bool canValidateChangeHeap_;
bool hasChangeHeap_;
bool supportsSimd_;
bool atomicsPresent_;
ScopedJSDeletePtr<ModuleCompileResults> compileResults_;
DebugOnly<bool> finishedFunctionBodies_;
@ -943,6 +948,7 @@ class MOZ_STACK_CLASS ModuleValidator
canValidateChangeHeap_(false),
hasChangeHeap_(false),
supportsSimd_(cx->jitSupportsSimd()),
atomicsPresent_(false),
compileResults_(nullptr),
finishedFunctionBodies_(false)
{
@ -1155,6 +1161,7 @@ class MOZ_STACK_CLASS ModuleValidator
Global* global = moduleLifo_.new_<Global>(Global::AtomicsBuiltinFunction);
if (!global)
return false;
atomicsPresent_ = true;
global->u.atomicsBuiltinFunc_ = func;
return globals_.putNew(varName, global);
}
@ -1509,6 +1516,14 @@ class MOZ_STACK_CLASS ModuleValidator
}
void startFunctionBodies() {
if (atomicsPresent_) {
for (GlobalMap::Range r = globals_.all() ; !r.empty() ; r.popFront()) {
Global* g = r.front().value();
if (g->isAnyArrayView())
g->setViewIsSharedView();
}
module_->setViewsAreShared();
}
module_->startFunctionBodies();
}
bool finishFunctionBodies(ScopedJSDeletePtr<ModuleCompileResults>* compileResults) {

View File

@ -0,0 +1,119 @@
// Transitional test cases, useful while Odin accepts both
// "Int32Array" and "SharedInt32Array" to construct a view onto shared
// memory but the former only when an atomic operation is referenced,
// as per spec. Eventually it will stop accepting "SharedInt32Array",
// because that name is going away.
//
// These should not run with --no-asmjs.
if (!isAsmJSCompilationAvailable())
quit(0);
//////////////////////////////////////////////////////////////////////
//
// Int8Array can be used on SharedArrayBuffer, if atomics are present
function m1(stdlib, ffi, heap) {
"use asm";
var i8 = new stdlib.Int8Array(heap);
var add = stdlib.Atomics.add;
function f() {
add(i8, 0, 1);
return 37;
}
return { f:f }
}
assertEq(isAsmJSModule(m1), true);
var { f } = m1(this, {}, new SharedArrayBuffer(65536));
assertEq(f(), 37);
//////////////////////////////////////////////////////////////////////
//
// SharedInt8Array can still be used on SharedArrayBuffer.
// (SharedInt8Array will eventually disappear, and this
// test case with it.)
function m2(stdlib, ffi, heap) {
"use asm";
var i8 = new stdlib.SharedInt8Array(heap);
var add = stdlib.Atomics.add;
function g() {
add(i8, 0, 1);
return 42;
}
return { g:g }
}
assertEq(isAsmJSModule(m2), true);
var { g } = m2(this, {}, new SharedArrayBuffer(65536));
assertEq(g(), 42);
//////////////////////////////////////////////////////////////////////
//
// SharedInt8Array still cannot be used on ArrayBuffer, even without
// atomics present.
// (SharedInt8Array will eventually disappear, and this
// test case with it.)
function m3(stdlib, ffi, heap) {
"use asm";
var i8 = new stdlib.SharedInt8Array(heap);
function h() {
return i8[0]|0;
}
return { h:h }
}
// Running the shell with -w you should see an error here.
assertEq(isAsmJSModule(m3), true);
try {
var wasThrown = false;
m3(this, {}, new ArrayBuffer(65536));
}
catch (e) {
wasThrown = true;
}
assertEq(wasThrown, true);
//////////////////////////////////////////////////////////////////////
//
// Int8Array cannot be used on SharedArrayBuffer if atomics are not imported.
// One argument for the restriction is that there are some optimizations
// that are legal if the memory is known not to be shared that are illegal
// when it is shared.
function m4(stdlib, ffi, heap) {
"use asm";
var i8 = new stdlib.Int8Array(heap);
function i() {
return i8[0]|0;
}
return { i:i }
}
assertEq(isAsmJSModule(m4), true);
// An error is not actually thrown because the link failure drops us
// back to JS execution and then the Int8Array constructor will copy data
// from the SharedArrayBuffer.
//
// Running the shell with -w you should see an error here.
var { i } = m4(this, {}, new SharedArrayBuffer(65536));
assertEq(isAsmJSFunction(i), false);

View File

@ -1,5 +1,5 @@
// |jit-test| test-also-noasmjs
if (!this.SharedArrayBuffer || !this.SharedInt32Array || !this.Atomics)
if (!this.SharedArrayBuffer || !this.Atomics)
quit();
// The code duplication below is very far from elegant but provides
@ -8,6 +8,27 @@ if (!this.SharedArrayBuffer || !this.SharedInt32Array || !this.Atomics)
load(libdir + "asm.js");
load(libdir + "asserts.js");
// This hack allows the test cases to run with --no-asmjs: the field values
// are basically ignored in asm.js mode, and the correct (Firefox-specific)
// field values are used in non-asm.js mode. If run in a non-Firefox
// browser that does not have the parallel type hierarchy this should also
// work.
//
// This hack will be removed when the parallel type hierarchy is removed
// from Firefox, bug 1176214.
const atomicStdlib = {
Atomics: Atomics,
Int8Array: this.SharedInt8Array ? SharedInt8Array : Int8Array,
Uint8Array: this.SharedUint8Array ? SharedUint8Array : Uint8Array,
Int16Array: this.SharedInt16Array ? SharedInt16Array : Int16Array,
Uint16Array: this.SharedUint16Array ? SharedUint16Array : Uint16Array,
Int32Array: this.SharedInt32Array ? SharedInt32Array : Int32Array,
Uint32Array: this.SharedUint32Array ? SharedUint32Array : Uint32Array,
Float32Array: this.SharedFloat32Array ? SharedFloat32Array : Float32Array,
Float64Array: this.SharedFloat64Array ? SharedFloat64Array : Float64Array
};
var loadModule_int32_code =
USE_ASM + `
var atomic_fence = stdlib.Atomics.fence;
@ -21,7 +42,7 @@ var loadModule_int32_code =
var atomic_or = stdlib.Atomics.or;
var atomic_xor = stdlib.Atomics.xor;
var i32a = new stdlib.SharedInt32Array(heap);
var i32a = new stdlib.Int32Array(heap);
function do_fence() {
atomic_fence();
@ -233,7 +254,7 @@ var loadModule_int32 = asmCompile('stdlib', 'foreign', 'heap', loadModule_int32_
function test_int32(heap) {
var i32a = new SharedInt32Array(heap);
var i32m = asmLink(loadModule_int32, this, {}, heap);
var i32m = asmLink(loadModule_int32, atomicStdlib, {}, heap);
var size = SharedInt32Array.BYTES_PER_ELEMENT;
@ -338,7 +359,7 @@ var loadModule_uint32_code =
var atomic_or = stdlib.Atomics.or;
var atomic_xor = stdlib.Atomics.xor;
var i32a = new stdlib.SharedUint32Array(heap);
var i32a = new stdlib.Uint32Array(heap);
// Load element 0
function do_load() {
@ -516,7 +537,7 @@ var loadModule_uint32 = asmCompile('stdlib', 'foreign', 'heap', loadModule_uint3
function test_uint32(heap) {
var i32a = new SharedUint32Array(heap);
var i32m = loadModule_uint32(this, {}, heap);
var i32m = loadModule_uint32(atomicStdlib, {}, heap);
var size = SharedUint32Array.BYTES_PER_ELEMENT;
@ -619,7 +640,7 @@ var loadModule_int16_code =
var atomic_or = stdlib.Atomics.or;
var atomic_xor = stdlib.Atomics.xor;
var i16a = new stdlib.SharedInt16Array(heap);
var i16a = new stdlib.Int16Array(heap);
function do_fence() {
atomic_fence();
@ -802,7 +823,7 @@ var loadModule_int16 = asmCompile('stdlib', 'foreign', 'heap', loadModule_int16_
function test_int16(heap) {
var i16a = new SharedInt16Array(heap);
var i16m = loadModule_int16(this, {}, heap);
var i16m = loadModule_int16(atomicStdlib, {}, heap);
var size = SharedInt16Array.BYTES_PER_ELEMENT;
@ -914,7 +935,7 @@ var loadModule_uint16_code =
var atomic_or = stdlib.Atomics.or;
var atomic_xor = stdlib.Atomics.xor;
var i16a = new stdlib.SharedUint16Array(heap);
var i16a = new stdlib.Uint16Array(heap);
// Load element 0
function do_load() {
@ -1092,7 +1113,7 @@ var loadModule_uint16 = asmCompile('stdlib', 'foreign', 'heap', loadModule_uint1
function test_uint16(heap) {
var i16a = new SharedUint16Array(heap);
var i16m = loadModule_uint16(this, {}, heap);
var i16m = loadModule_uint16(atomicStdlib, {}, heap);
var size = SharedUint16Array.BYTES_PER_ELEMENT;
@ -1202,7 +1223,7 @@ var loadModule_int8_code =
var atomic_or = stdlib.Atomics.or;
var atomic_xor = stdlib.Atomics.xor;
var i8a = new stdlib.SharedInt8Array(heap);
var i8a = new stdlib.Int8Array(heap);
// Load element 0
function do_load() {
@ -1380,7 +1401,7 @@ var loadModule_int8 = asmCompile('stdlib', 'foreign', 'heap', loadModule_int8_co
function test_int8(heap) {
var i8a = new SharedInt8Array(heap);
var i8m = loadModule_int8(this, {}, heap);
var i8m = loadModule_int8(atomicStdlib, {}, heap);
for ( var i=0 ; i < i8a.length ; i++ )
i8a[i] = 0;
@ -1483,7 +1504,7 @@ var loadModule_uint8_code =
var atomic_or = stdlib.Atomics.or;
var atomic_xor = stdlib.Atomics.xor;
var i8a = new stdlib.SharedUint8Array(heap);
var i8a = new stdlib.Uint8Array(heap);
// Load element 0
function do_load() {
@ -1661,7 +1682,7 @@ var loadModule_uint8 = asmCompile('stdlib', 'foreign', 'heap', loadModule_uint8_
function test_uint8(heap) {
var i8a = new SharedUint8Array(heap);
var i8m = loadModule_uint8(this, {}, heap);
var i8m = loadModule_uint8(atomicStdlib, {}, heap);
for ( var i=0 ; i < i8a.length ; i++ )
i8a[i] = 0;
@ -1816,7 +1837,7 @@ var loadModule_misc_code =
var loadModule_misc = asmCompile('stdlib', 'foreign', 'heap', loadModule_misc_code);
function test_misc(heap) {
var misc = loadModule_misc(this, {}, heap);
var misc = loadModule_misc(atomicStdlib, {}, heap);
assertEq(misc.ilf1(), 1);
assertEq(misc.ilf2(), 1);
@ -1848,7 +1869,7 @@ setARMHwCapFlags('vfp');
asmCompile('stdlib', 'ffi', 'heap',
USE_ASM + `
var atomic_exchange = stdlib.Atomics.exchange;
var i8a = new stdlib.SharedInt8Array(heap);
var i8a = new stdlib.Int8Array(heap);
function do_xchg() {
var v = 0;

View File

@ -0,0 +1,9 @@
var x = {};
Reflect.set(x, "prop", 5, Object.prototype);
var y = {};
Reflect.set(y, "prop", 6, Object.prototype);
assertEq(x.hasOwnProperty("prop"), false);
assertEq(y.hasOwnProperty("prop"), false);
assertEq(Object.prototype.prop, 6);
reportCompare(0, 0, "ok");

View File

@ -2244,7 +2244,7 @@ SetExistingProperty(JSContext* cx, HandleNativeObject obj, HandleId id, HandleVa
Rooted<ArrayObject*> arr(cx, &pobj->as<ArrayObject>());
return ArraySetLength(cx, arr, id, shape->attributes(), v, result);
}
return NativeSetExistingDataProperty(cx, obj, shape, v, receiver, result);
return NativeSetExistingDataProperty(cx, pobj, shape, v, receiver, result);
}
// SpiderMonkey special case: assigning to an inherited slotless

View File

@ -14,8 +14,10 @@
#include "ActiveLayerTracker.h"
#include "BasicLayers.h"
#include "ImageContainer.h"
#include "ImageLayers.h"
#include "LayerTreeInvalidation.h"
#include "Layers.h"
#include "LayerUserData.h"
#include "MaskLayerImageCache.h"
#include "UnitTransforms.h"
#include "Units.h"
@ -87,6 +89,22 @@ uint8_t gLayerManagerUserData;
*/
uint8_t gMaskLayerUserData;
FrameLayerBuilder::FrameLayerBuilder()
: mRetainingManager(nullptr)
, mDetectedDOMModification(false)
, mInvalidateAllLayers(false)
, mInLayerTreeCompressionMode(false)
, mContainerLayerGeneration(0)
, mMaxContainerLayerGeneration(0)
{
MOZ_COUNT_CTOR(FrameLayerBuilder);
}
FrameLayerBuilder::~FrameLayerBuilder()
{
MOZ_COUNT_DTOR(FrameLayerBuilder);
}
FrameLayerBuilder::DisplayItemData::DisplayItemData(LayerManagerData* aParent, uint32_t aKey,
Layer* aLayer, nsIFrame* aFrame)
@ -4571,6 +4589,13 @@ FrameLayerBuilder::StoreDataForFrame(nsIFrame* aFrame,
lmd->mDisplayItems.PutEntry(data);
}
FrameLayerBuilder::ClippedDisplayItem::ClippedDisplayItem(nsDisplayItem* aItem,
uint32_t aGeneration)
: mItem(aItem)
, mContainerLayerGeneration(aGeneration)
{
}
FrameLayerBuilder::ClippedDisplayItem::~ClippedDisplayItem()
{
if (mInactiveLayerManager) {
@ -4578,6 +4603,27 @@ FrameLayerBuilder::ClippedDisplayItem::~ClippedDisplayItem()
}
}
FrameLayerBuilder::PaintedLayerItemsEntry::PaintedLayerItemsEntry(const PaintedLayer *aKey)
: nsPtrHashKey<PaintedLayer>(aKey)
, mContainerLayerFrame(nullptr)
, mLastCommonClipCount(0)
, mContainerLayerGeneration(0)
, mHasExplicitLastPaintOffset(false)
, mCommonClipCount(0)
{
}
FrameLayerBuilder::PaintedLayerItemsEntry::PaintedLayerItemsEntry(const PaintedLayerItemsEntry& aOther)
: nsPtrHashKey<PaintedLayer>(aOther.mKey)
, mItems(aOther.mItems)
{
NS_ERROR("Should never be called, since we ALLOW_MEMMOVE");
}
FrameLayerBuilder::PaintedLayerItemsEntry::~PaintedLayerItemsEntry()
{
}
void
FrameLayerBuilder::AddLayerDisplayItem(Layer* aLayer,
nsDisplayItem* aItem,

View File

@ -11,10 +11,10 @@
#include "nsTArray.h"
#include "nsRegion.h"
#include "nsIFrame.h"
#include "ImageLayers.h"
#include "DisplayItemClip.h"
#include "mozilla/layers/LayersTypes.h"
#include "LayerState.h"
#include "LayerUserData.h"
class nsDisplayListBuilder;
class nsDisplayList;
@ -28,6 +28,7 @@ class ContainerLayer;
class LayerManager;
class BasicLayerManager;
class PaintedLayer;
class ImageLayer;
} // namespace layers
namespace gfx {
@ -172,20 +173,8 @@ public:
typedef layers::BasicLayerManager BasicLayerManager;
typedef layers::EventRegions EventRegions;
FrameLayerBuilder() :
mRetainingManager(nullptr),
mDetectedDOMModification(false),
mInvalidateAllLayers(false),
mInLayerTreeCompressionMode(false),
mContainerLayerGeneration(0),
mMaxContainerLayerGeneration(0)
{
MOZ_COUNT_CTOR(FrameLayerBuilder);
}
~FrameLayerBuilder()
{
MOZ_COUNT_DTOR(FrameLayerBuilder);
}
FrameLayerBuilder();
~FrameLayerBuilder();
static void Shutdown();
@ -578,11 +567,7 @@ protected:
* PaintedLayer.
*/
struct ClippedDisplayItem {
ClippedDisplayItem(nsDisplayItem* aItem, uint32_t aGeneration)
: mItem(aItem), mContainerLayerGeneration(aGeneration)
{
}
ClippedDisplayItem(nsDisplayItem* aItem, uint32_t aGeneration);
~ClippedDisplayItem();
nsDisplayItem* mItem;
@ -623,19 +608,9 @@ protected:
public:
class PaintedLayerItemsEntry : public nsPtrHashKey<PaintedLayer> {
public:
explicit PaintedLayerItemsEntry(const PaintedLayer *key)
: nsPtrHashKey<PaintedLayer>(key)
, mContainerLayerFrame(nullptr)
, mLastCommonClipCount(0)
, mContainerLayerGeneration(0)
, mHasExplicitLastPaintOffset(false)
, mCommonClipCount(0)
{}
PaintedLayerItemsEntry(const PaintedLayerItemsEntry &toCopy) :
nsPtrHashKey<PaintedLayer>(toCopy.mKey), mItems(toCopy.mItems)
{
NS_ERROR("Should never be called, since we ALLOW_MEMMOVE");
}
explicit PaintedLayerItemsEntry(const PaintedLayer *key);
PaintedLayerItemsEntry(const PaintedLayerItemsEntry&);
~PaintedLayerItemsEntry();
nsTArray<ClippedDisplayItem> mItems;
nsIFrame* mContainerLayerFrame;

View File

@ -401,13 +401,14 @@ struct ColorStop {
};
/* Local functions */
static void DrawBorderImage(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
nsIFrame* aForFrame,
const nsRect& aBorderArea,
const nsStyleBorder& aStyleBorder,
const nsRect& aDirtyRect,
Sides aSkipSides);
static DrawResult DrawBorderImage(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
nsIFrame* aForFrame,
const nsRect& aBorderArea,
const nsStyleBorder& aStyleBorder,
const nsRect& aDirtyRect,
Sides aSkipSides,
PaintBorderFlags aFlags);
static nscolor MakeBevelColor(mozilla::css::Side whichSide, uint8_t style,
nscolor aBackgroundColor,
@ -616,13 +617,14 @@ nsCSSRendering::ComputePixelRadii(const nscoord *aAppUnitsRadii,
radii[NS_CORNER_BOTTOM_LEFT_Y]);
}
void
DrawResult
nsCSSRendering::PaintBorder(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
nsIFrame* aForFrame,
const nsRect& aDirtyRect,
const nsRect& aBorderArea,
nsStyleContext* aStyleContext,
PaintBorderFlags aFlags,
Sides aSkipSides)
{
PROFILER_LABEL("nsCSSRendering", "PaintBorder",
@ -633,10 +635,9 @@ nsCSSRendering::PaintBorder(nsPresContext* aPresContext,
// Don't check RelevantLinkVisited here, since we want to take the
// same amount of time whether or not it's true.
if (!styleIfVisited) {
PaintBorderWithStyleBorder(aPresContext, aRenderingContext, aForFrame,
aDirtyRect, aBorderArea, *styleBorder,
aStyleContext, aSkipSides);
return;
return PaintBorderWithStyleBorder(aPresContext, aRenderingContext, aForFrame,
aDirtyRect, aBorderArea, *styleBorder,
aStyleContext, aFlags, aSkipSides);
}
nsStyleBorder newStyleBorder(*styleBorder);
@ -650,17 +651,20 @@ nsCSSRendering::PaintBorder(nsPresContext* aPresContext,
aStyleContext->GetVisitedDependentColor(
nsCSSProps::SubpropertyEntryFor(eCSSProperty_border_color)[side]));
}
PaintBorderWithStyleBorder(aPresContext, aRenderingContext, aForFrame,
aDirtyRect, aBorderArea, newStyleBorder,
aStyleContext, aSkipSides);
DrawResult result =
PaintBorderWithStyleBorder(aPresContext, aRenderingContext, aForFrame,
aDirtyRect, aBorderArea, newStyleBorder,
aStyleContext, aFlags, aSkipSides);
// We could do something fancy to avoid the TrackImage/UntrackImage
// work, but it doesn't seem worth it. (We need to call UntrackImage
// since we're not going through nsStyleBorder::Destroy.)
newStyleBorder.UntrackImage(aPresContext);
return result;
}
void
DrawResult
nsCSSRendering::PaintBorderWithStyleBorder(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
nsIFrame* aForFrame,
@ -668,6 +672,7 @@ nsCSSRendering::PaintBorderWithStyleBorder(nsPresContext* aPresContext,
const nsRect& aBorderArea,
const nsStyleBorder& aStyleBorder,
nsStyleContext* aStyleContext,
PaintBorderFlags aFlags,
Sides aSkipSides)
{
DrawTarget& aDrawTarget = *aRenderingContext.GetDrawTarget();
@ -680,14 +685,26 @@ nsCSSRendering::PaintBorderWithStyleBorder(nsPresContext* aPresContext,
const nsStyleDisplay* displayData = aStyleContext->StyleDisplay();
if (displayData->mAppearance) {
nsITheme *theme = aPresContext->GetTheme();
if (theme && theme->ThemeSupportsWidget(aPresContext, aForFrame, displayData->mAppearance))
return; // Let the theme handle it.
if (theme &&
theme->ThemeSupportsWidget(aPresContext, aForFrame,
displayData->mAppearance)) {
return DrawResult::SUCCESS; // Let the theme handle it.
}
}
if (aStyleBorder.IsBorderImageLoaded()) {
DrawBorderImage(aPresContext, aRenderingContext, aForFrame,
aBorderArea, aStyleBorder, aDirtyRect, aSkipSides);
return;
return DrawBorderImage(aPresContext, aRenderingContext, aForFrame,
aBorderArea, aStyleBorder, aDirtyRect,
aSkipSides, aFlags);
}
DrawResult result = DrawResult::SUCCESS;
// If we had a border-image, but it wasn't loaded, then we should return
// DrawResult::NOT_READY; we'll want to try again if we do a paint with sync
// decoding enabled.
if (aStyleBorder.mBorderImageSource.GetType() != eStyleImageType_Null) {
result = DrawResult::NOT_READY;
}
// Get our style context's color struct.
@ -705,7 +722,7 @@ nsCSSRendering::PaintBorderWithStyleBorder(nsPresContext* aPresContext,
if (0 == border.left && 0 == border.right &&
0 == border.top && 0 == border.bottom) {
// Empty border area
return;
return result;
}
// Compute the outermost boundary of the area that might be painted.
@ -789,6 +806,8 @@ nsCSSRendering::PaintBorderWithStyleBorder(nsPresContext* aPresContext,
ctx->Restore();
PrintAsStringNewline();
return result;
}
static nsRect
@ -3347,22 +3366,28 @@ nsCSSRendering::GetBackgroundLayerRect(nsPresContext* aPresContext,
return state.mFillArea;
}
static void
static DrawResult
DrawBorderImage(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
nsIFrame* aForFrame,
const nsRect& aBorderArea,
const nsStyleBorder& aStyleBorder,
const nsRect& aDirtyRect,
Sides aSkipSides)
Sides aSkipSides,
PaintBorderFlags aFlags)
{
NS_PRECONDITION(aStyleBorder.IsBorderImageLoaded(),
"drawing border image that isn't successfully loaded");
if (aDirtyRect.IsEmpty())
return;
if (aDirtyRect.IsEmpty()) {
return DrawResult::SUCCESS;
}
nsImageRenderer renderer(aForFrame, &aStyleBorder.mBorderImageSource, 0);
uint32_t irFlags = 0;
if (aFlags & PaintBorderFlags::SYNC_DECODE_IMAGES) {
irFlags |= nsImageRenderer::FLAG_SYNC_DECODE_IMAGES;
}
nsImageRenderer renderer(aForFrame, &aStyleBorder.mBorderImageSource, irFlags);
// Ensure we get invalidated for loads and animations of the image.
// We need to do this here because this might be the only code that
@ -3373,7 +3398,7 @@ DrawBorderImage(nsPresContext* aPresContext,
aForFrame->AssociateImage(aStyleBorder.mBorderImageSource, aPresContext);
if (!renderer.PrepareImage()) {
return;
return renderer.PrepareResult();
}
// NOTE: no Save() yet, we do that later by calling autoSR.EnsureSaved()
@ -3549,6 +3574,8 @@ DrawBorderImage(nsPresContext* aPresContext,
slice.bottom,
};
DrawResult result = DrawResult::SUCCESS;
for (int i = LEFT; i <= RIGHT; i++) {
for (int j = TOP; j <= BOTTOM; j++) {
uint8_t fillStyleH, fillStyleV;
@ -3633,16 +3660,19 @@ DrawBorderImage(nsPresContext* aPresContext,
nsRect subArea(sliceX[i], sliceY[j], sliceWidth[i], sliceHeight[j]);
nsIntRect intSubArea = subArea.ToOutsidePixels(nsPresContext::AppUnitsPerCSSPixel());
renderer.DrawBorderImageComponent(aPresContext,
aRenderingContext, aDirtyRect,
destArea, CSSIntRect(intSubArea.x,
intSubArea.y,
intSubArea.width,
intSubArea.height),
fillStyleH, fillStyleV,
unitSize, j * (RIGHT + 1) + i);
result &=
renderer.DrawBorderImageComponent(aPresContext,
aRenderingContext, aDirtyRect,
destArea, CSSIntRect(intSubArea.x,
intSubArea.y,
intSubArea.width,
intSubArea.height),
fillStyleH, fillStyleV,
unitSize, j * (RIGHT + 1) + i);
}
}
return result;
}
// Begin table border-collapsing section
@ -5031,17 +5061,18 @@ nsImageRenderer::Draw(nsPresContext* aPresContext,
}
nsCOMPtr<imgIContainer> image(ImageOps::CreateFromDrawable(drawable));
nsLayoutUtils::DrawImage(*aRenderingContext.ThebesContext(),
aPresContext, image,
filter, aDest, aFill, aAnchor, aDirtyRect,
ConvertImageRendererToDrawFlags(mFlags));
DrawResult result =
nsLayoutUtils::DrawImage(*aRenderingContext.ThebesContext(),
aPresContext, image,
filter, aDest, aFill, aAnchor, aDirtyRect,
ConvertImageRendererToDrawFlags(mFlags));
if (op != CompositionOp::OP_OVER) {
ctx->PopGroupToSource();
ctx->Paint();
}
return DrawResult::SUCCESS;
return result;
}
case eStyleImageType_Null:
default:
@ -5177,7 +5208,7 @@ RequiresScaling(const nsRect& aFill,
aUnitSize.height != aFill.height);
}
void
DrawResult
nsImageRenderer::DrawBorderImageComponent(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
@ -5190,10 +5221,10 @@ nsImageRenderer::DrawBorderImageComponent(nsPresContext* aPresContext,
{
if (!IsReady()) {
NS_NOTREACHED("Ensure PrepareImage() has returned true before calling me");
return;
return DrawResult::BAD_ARGS;
}
if (aFill.IsEmpty() || aSrc.IsEmpty()) {
return;
return DrawResult::SUCCESS;
}
if (mType == eStyleImageType_Image || mType == eStyleImageType_Element) {
@ -5219,7 +5250,7 @@ nsImageRenderer::DrawBorderImageComponent(nsPresContext* aPresContext,
aRenderingContext);
if (!drawable) {
NS_WARNING("Could not create drawable for element");
return;
return DrawResult::TEMPORARY_ERROR;
}
nsCOMPtr<imgIContainer> image(ImageOps::CreateFromDrawable(drawable));
@ -5229,32 +5260,30 @@ nsImageRenderer::DrawBorderImageComponent(nsPresContext* aPresContext,
Filter filter = nsLayoutUtils::GetGraphicsFilterForFrame(mForFrame);
if (!RequiresScaling(aFill, aHFill, aVFill, aUnitSize)) {
nsLayoutUtils::DrawSingleImage(*aRenderingContext.ThebesContext(),
aPresContext,
subImage,
filter,
aFill, aDirtyRect,
nullptr,
imgIContainer::FLAG_NONE);
return;
return nsLayoutUtils::DrawSingleImage(*aRenderingContext.ThebesContext(),
aPresContext,
subImage,
filter,
aFill, aDirtyRect,
nullptr,
ConvertImageRendererToDrawFlags(mFlags));
}
nsRect tile = ComputeTile(aFill, aHFill, aVFill, aUnitSize);
nsLayoutUtils::DrawImage(*aRenderingContext.ThebesContext(),
aPresContext,
subImage,
filter,
tile, aFill, tile.TopLeft(), aDirtyRect,
imgIContainer::FLAG_NONE);
return;
return nsLayoutUtils::DrawImage(*aRenderingContext.ThebesContext(),
aPresContext,
subImage,
filter,
tile, aFill, tile.TopLeft(), aDirtyRect,
ConvertImageRendererToDrawFlags(mFlags));
}
nsRect destTile = RequiresScaling(aFill, aHFill, aVFill, aUnitSize)
? ComputeTile(aFill, aHFill, aVFill, aUnitSize)
: aFill;
Draw(aPresContext, aRenderingContext, aDirtyRect, destTile,
aFill, destTile.TopLeft(), aSrc);
return Draw(aPresContext, aRenderingContext, aDirtyRect, destTile,
aFill, destTile.TopLeft(), aSrc);
}
bool

View File

@ -13,6 +13,7 @@
#include "imgIContainer.h"
#include "mozilla/gfx/PathHelpers.h"
#include "mozilla/gfx/Rect.h"
#include "mozilla/TypedEnumBits.h"
#include "nsLayoutUtils.h"
#include "nsStyleStruct.h"
#include "nsIFrame.h"
@ -99,6 +100,12 @@ struct CSSSizeOrRatio
bool mHasHeight;
};
enum class PaintBorderFlags : uint8_t
{
SYNC_DECODE_IMAGES = 1 << 0
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(PaintBorderFlags)
} // namespace mozilla
/**
@ -225,7 +232,7 @@ public:
* 3 4 5
* 6 7 8
*/
void
DrawResult
DrawBorderImageComponent(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
@ -380,27 +387,29 @@ struct nsCSSRendering {
* for borders. aSkipSides says which sides to skip
* when rendering, the default is to skip none.
*/
static void PaintBorder(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
nsIFrame* aForFrame,
const nsRect& aDirtyRect,
const nsRect& aBorderArea,
nsStyleContext* aStyleContext,
Sides aSkipSides = Sides());
static DrawResult PaintBorder(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
nsIFrame* aForFrame,
const nsRect& aDirtyRect,
const nsRect& aBorderArea,
nsStyleContext* aStyleContext,
mozilla::PaintBorderFlags aFlags,
Sides aSkipSides = Sides());
/**
* Like PaintBorder, but taking an nsStyleBorder argument instead of
* getting it from aStyleContext. aSkipSides says which sides to skip
* when rendering, the default is to skip none.
*/
static void PaintBorderWithStyleBorder(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
nsIFrame* aForFrame,
const nsRect& aDirtyRect,
const nsRect& aBorderArea,
const nsStyleBorder& aBorderStyle,
nsStyleContext* aStyleContext,
Sides aSkipSides = Sides());
static DrawResult PaintBorderWithStyleBorder(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
nsIFrame* aForFrame,
const nsRect& aDirtyRect,
const nsRect& aBorderArea,
const nsStyleBorder& aBorderStyle,
nsStyleContext* aStyleContext,
mozilla::PaintBorderFlags aFlags,
Sides aSkipSides = Sides());
/**

View File

@ -2557,7 +2557,8 @@ nsDisplayBackgroundImage::ConfigureLayer(ImageLayer* aLayer,
if (imageWidth > 0 && imageHeight > 0) {
// We're actually using the ImageContainer. Let our frame know that it
// should consider itself to have painted successfully.
nsDisplayBackgroundGeometry::UpdateDrawResult(this, mozilla::image::DrawResult::SUCCESS);
nsDisplayBackgroundGeometry::UpdateDrawResult(this,
image::DrawResult::SUCCESS);
}
// XXX(seth): Right now we ignore aParameters.Scale() and
@ -2734,7 +2735,7 @@ nsDisplayBackgroundImage::PaintInternal(nsDisplayListBuilder* aBuilder,
uint32_t flags = aBuilder->GetBackgroundPaintFlags();
CheckForBorderItem(this, flags);
mozilla::image::DrawResult result =
image::DrawResult result =
nsCSSRendering::PaintBackground(mFrame->PresContext(), *aCtx, mFrame,
aBounds,
nsRect(offset, mFrame->GetSize()),
@ -3346,6 +3347,7 @@ nsDisplayBorder::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
{
const nsDisplayBorderGeometry* geometry = static_cast<const nsDisplayBorderGeometry*>(aGeometry);
bool snap;
if (!geometry->mBounds.IsEqualInterior(GetBounds(aBuilder, &snap)) ||
!geometry->mContentRect.IsEqualInterior(GetContentRect())) {
// We can probably get away with only invalidating the difference
@ -3353,17 +3355,31 @@ nsDisplayBorder::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
// is apparently painting a background with this?
aInvalidRegion->Or(GetBounds(aBuilder, &snap), geometry->mBounds);
}
if (aBuilder->ShouldSyncDecodeImages() &&
geometry->ShouldInvalidateToSyncDecodeImages()) {
aInvalidRegion->Or(*aInvalidRegion, GetBounds(aBuilder, &snap));
}
}
void
nsDisplayBorder::Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx) {
nsPoint offset = ToReferenceFrame();
nsCSSRendering::PaintBorder(mFrame->PresContext(), *aCtx, mFrame,
mVisibleRect,
nsRect(offset, mFrame->GetSize()),
mFrame->StyleContext(),
mFrame->GetSkipSides());
PaintBorderFlags flags = aBuilder->ShouldSyncDecodeImages()
? PaintBorderFlags::SYNC_DECODE_IMAGES
: PaintBorderFlags();
image::DrawResult result =
nsCSSRendering::PaintBorder(mFrame->PresContext(), *aCtx, mFrame,
mVisibleRect,
nsRect(offset, mFrame->GetSize()),
mFrame->StyleContext(),
flags,
mFrame->GetSkipSides());
nsDisplayBorderGeometry::UpdateDrawResult(this, result);
}
nsRect
@ -4149,6 +4165,17 @@ nsDisplayBlendContainer::BuildLayer(nsDisplayListBuilder* aBuilder,
return container.forget();
}
LayerState
nsDisplayBlendContainer::GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters)
{
if (mCanBeActive && aManager->SupportsMixBlendModes(mContainedBlendModes)) {
return mozilla::LAYER_ACTIVE;
}
return mozilla::LAYER_INACTIVE;
}
bool nsDisplayBlendContainer::TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) {
if (aItem->GetType() != TYPE_BLEND_CONTAINER)
return false;
@ -5387,9 +5414,11 @@ nsDisplayItem::LayerState
nsDisplayTransform::GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters) {
// If the transform is 3d, or the layer takes part in preserve-3d sorting
// then we *always* want this to be an active layer.
if (!GetTransform().Is2D() || mFrame->Combines3DTransformWithAncestors()) {
// If the transform is 3d, the layer takes part in preserve-3d
// sorting, or the layer is a separator then we *always* want this
// to be an active layer.
if (!GetTransform().Is2D() || mFrame->Combines3DTransformWithAncestors() ||
mIsTransformSeparator) {
return LAYER_ACTIVE_FORCE;
}
// Here we check if the *post-transform* bounds of this item are big enough
@ -5560,7 +5589,7 @@ nsDisplayTransform::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
return mBounds;
}
if (mFrame->Extend3DContext()) {
if (mFrame->Extend3DContext() && !mIsTransformSeparator) {
return nsRect();
}

View File

@ -15,12 +15,12 @@
#include "mozilla/Attributes.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/EnumSet.h"
#include "nsCOMPtr.h"
#include "nsContainerFrame.h"
#include "nsPoint.h"
#include "nsRect.h"
#include "plarena.h"
#include "Layers.h"
#include "nsRegion.h"
#include "nsDisplayListInvalidation.h"
#include "DisplayListClipState.h"
@ -37,6 +37,7 @@
class nsIContent;
class nsRenderingContext;
class nsDisplayList;
class nsDisplayTableItem;
class nsISelection;
class nsDisplayLayerEventRegions;
@ -553,8 +554,7 @@ public:
/**
* Notifies the builder that a particular themed widget exists
* at the given rectangle within the currently built display list.
* For certain appearance values (currently only
* NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR, NS_THEME_TOOLBAR and
* For certain appearance values (currently only NS_THEME_TOOLBAR and
* NS_THEME_WINDOW_TITLEBAR) this gets called during every display list
* construction, for every themed widget of the right type within the
* display list, except for themed widgets which are transformed or have
@ -3287,13 +3287,7 @@ public:
const ContainerLayerParameters& aContainerParameters) override;
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters) override
{
if (mCanBeActive && aManager->SupportsMixBlendModes(mContainedBlendModes)) {
return mozilla::LAYER_ACTIVE;
}
return mozilla::LAYER_INACTIVE;
}
const ContainerLayerParameters& aParameters) override;
virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) override;
virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override {
return false;

View File

@ -47,6 +47,7 @@ nsDisplayItemBoundsGeometry::nsDisplayItemBoundsGeometry(nsDisplayItem* aItem, n
nsDisplayBorderGeometry::nsDisplayBorderGeometry(nsDisplayItem* aItem, nsDisplayListBuilder* aBuilder)
: nsDisplayItemGeometry(aItem, aBuilder)
, nsImageGeometryMixin(aItem, aBuilder)
, mContentRect(aItem->GetContentRect())
{}

View File

@ -172,7 +172,9 @@ public:
bool mHasRoundedCorners;
};
class nsDisplayBorderGeometry : public nsDisplayItemGeometry
class nsDisplayBorderGeometry
: public nsDisplayItemGeometry
, public nsImageGeometryMixin<nsDisplayBorderGeometry>
{
public:
nsDisplayBorderGeometry(nsDisplayItem* aItem, nsDisplayListBuilder* aBuilder);

View File

@ -56,6 +56,7 @@
#include "mozilla/dom/TabParent.h"
#include "nsRefreshDriver.h"
#include "Layers.h"
#include "LayerUserData.h"
#include "ClientLayerManager.h"
#include "mozilla/dom/NotifyPaintEvent.h"
#include "gfxPrefs.h"

View File

@ -1571,9 +1571,10 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime)
presContext->NotifyFontFaceSetOnRefresh();
}
NS_RELEASE(shell);
mNeedToRecomputeVisibility = true;
}
mNeedToRecomputeVisibility = true;
if (tracingStyleFlush) {
profiler_tracing("Paint", "Styles", TRACING_INTERVAL_END);
@ -1617,9 +1618,9 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime)
presContext->NotifyFontFaceSetOnRefresh();
}
NS_RELEASE(shell);
}
mNeedToRecomputeVisibility = true;
mNeedToRecomputeVisibility = true;
}
if (tracingLayoutFlush) {
profiler_tracing("Paint", "Reflow", TRACING_INTERVAL_END);

View File

@ -50,6 +50,7 @@
#include "nsFocusManager.h"
#include "ThirdPartyUtil.h"
#include "nsStructuredCloneContainer.h"
#include "gfxPlatform.h"
#include "nsIEventListenerService.h"
#include "nsIMessageManager.h"

View File

@ -19,6 +19,7 @@
#define HOVER "hover"
#define FOCUS "focus"
using namespace mozilla;
using namespace mozilla::image;
nsButtonFrameRenderer::nsButtonFrameRenderer()
@ -141,33 +142,6 @@ private:
nsButtonFrameRenderer* mBFR;
};
nsRect
nsDisplayButtonBorderBackground::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
*aSnap = false;
return aBuilder->IsForEventDelivery() ? nsRect(ToReferenceFrame(), mFrame->GetSize())
: mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame();
}
class nsDisplayButtonForeground : public nsDisplayItem {
public:
nsDisplayButtonForeground(nsDisplayListBuilder* aBuilder,
nsButtonFrameRenderer* aRenderer)
: nsDisplayItem(aBuilder, aRenderer->GetFrame()), mBFR(aRenderer) {
MOZ_COUNT_CTOR(nsDisplayButtonForeground);
}
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplayButtonForeground() {
MOZ_COUNT_DTOR(nsDisplayButtonForeground);
}
#endif
virtual void Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx) override;
NS_DISPLAY_DECL_NAME("ButtonForeground", TYPE_BUTTON_FOREGROUND)
private:
nsButtonFrameRenderer* mBFR;
};
nsDisplayItemGeometry*
nsDisplayButtonBorderBackground::AllocateGeometry(nsDisplayListBuilder* aBuilder)
{
@ -175,9 +149,10 @@ nsDisplayButtonBorderBackground::AllocateGeometry(nsDisplayListBuilder* aBuilder
}
void
nsDisplayButtonBorderBackground::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion *aInvalidRegion)
nsDisplayButtonBorderBackground::ComputeInvalidationRegion(
nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion *aInvalidRegion)
{
auto geometry =
static_cast<const nsDisplayItemGenericImageGeometry*>(aGeometry);
@ -200,12 +175,66 @@ void nsDisplayButtonBorderBackground::Paint(nsDisplayListBuilder* aBuilder,
// draw the border and background inside the focus and outline borders
DrawResult result =
mBFR->PaintBorderAndBackground(pc, *aCtx, mVisibleRect, r,
aBuilder->GetBackgroundPaintFlags());
mBFR->PaintBorderAndBackground(aBuilder, pc, *aCtx, mVisibleRect, r);
nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
}
nsRect
nsDisplayButtonBorderBackground::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
*aSnap = false;
return aBuilder->IsForEventDelivery() ? nsRect(ToReferenceFrame(), mFrame->GetSize())
: mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame();
}
class nsDisplayButtonForeground : public nsDisplayItem {
public:
nsDisplayButtonForeground(nsDisplayListBuilder* aBuilder,
nsButtonFrameRenderer* aRenderer)
: nsDisplayItem(aBuilder, aRenderer->GetFrame()), mBFR(aRenderer) {
MOZ_COUNT_CTOR(nsDisplayButtonForeground);
}
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplayButtonForeground() {
MOZ_COUNT_DTOR(nsDisplayButtonForeground);
}
#endif
nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override;
void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion *aInvalidRegion) override;
virtual void Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx) override;
NS_DISPLAY_DECL_NAME("ButtonForeground", TYPE_BUTTON_FOREGROUND)
private:
nsButtonFrameRenderer* mBFR;
};
nsDisplayItemGeometry*
nsDisplayButtonForeground::AllocateGeometry(nsDisplayListBuilder* aBuilder)
{
return new nsDisplayItemGenericImageGeometry(this, aBuilder);
}
void
nsDisplayButtonForeground::ComputeInvalidationRegion(
nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion* aInvalidRegion)
{
auto geometry =
static_cast<const nsDisplayItemGenericImageGeometry*>(aGeometry);
if (aBuilder->ShouldSyncDecodeImages() &&
geometry->ShouldInvalidateToSyncDecodeImages()) {
bool snap;
aInvalidRegion->Or(*aInvalidRegion, GetBounds(aBuilder, &snap));
}
nsDisplayItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion);
}
void nsDisplayButtonForeground::Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx)
{
@ -213,9 +242,14 @@ void nsDisplayButtonForeground::Paint(nsDisplayListBuilder* aBuilder,
const nsStyleDisplay *disp = mFrame->StyleDisplay();
if (!mFrame->IsThemed(disp) ||
!presContext->GetTheme()->ThemeDrawsFocusForWidget(disp->mAppearance)) {
// draw the focus and outline borders
nsRect r = nsRect(ToReferenceFrame(), mFrame->GetSize());
mBFR->PaintOutlineAndFocusBorders(presContext, *aCtx, mVisibleRect, r);
// Draw the focus and outline borders.
DrawResult result =
mBFR->PaintOutlineAndFocusBorders(aBuilder, presContext, *aCtx,
mVisibleRect, r);
nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
}
}
@ -244,11 +278,13 @@ nsButtonFrameRenderer::DisplayButton(nsDisplayListBuilder* aBuilder,
return NS_OK;
}
void
nsButtonFrameRenderer::PaintOutlineAndFocusBorders(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
const nsRect& aRect)
DrawResult
nsButtonFrameRenderer::PaintOutlineAndFocusBorders(
nsDisplayListBuilder* aBuilder,
nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
const nsRect& aRect)
{
// once we have all that we'll draw the focus if we have it. We will
// need to draw 2 focuses, the inner and the outer. This is so we
@ -259,13 +295,20 @@ nsButtonFrameRenderer::PaintOutlineAndFocusBorders(nsPresContext* aPresContext,
nsRect rect;
PaintBorderFlags flags = aBuilder->ShouldSyncDecodeImages()
? PaintBorderFlags::SYNC_DECODE_IMAGES
: PaintBorderFlags();
DrawResult result = DrawResult::SUCCESS;
if (mOuterFocusStyle) {
// ---------- paint the outer focus border -------------
GetButtonOuterFocusRect(aRect, rect);
nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, mFrame,
aDirtyRect, rect, mOuterFocusStyle);
result &=
nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, mFrame,
aDirtyRect, rect, mOuterFocusStyle, flags);
}
if (mInnerFocusStyle) {
@ -273,19 +316,22 @@ nsButtonFrameRenderer::PaintOutlineAndFocusBorders(nsPresContext* aPresContext,
GetButtonInnerFocusRect(aRect, rect);
nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, mFrame,
aDirtyRect, rect, mInnerFocusStyle);
result &=
nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, mFrame,
aDirtyRect, rect, mInnerFocusStyle, flags);
}
return result;
}
DrawResult
nsButtonFrameRenderer::PaintBorderAndBackground(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
const nsRect& aRect,
uint32_t aBGFlags)
nsButtonFrameRenderer::PaintBorderAndBackground(
nsDisplayListBuilder* aBuilder,
nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
const nsRect& aRect)
{
// get the button rect this is inside the focus and outline rects
nsRect buttonRect;
@ -293,13 +339,21 @@ nsButtonFrameRenderer::PaintBorderAndBackground(nsPresContext* aPresContext,
nsStyleContext* context = mFrame->StyleContext();
uint32_t bgFlags = aBuilder->GetBackgroundPaintFlags();
PaintBorderFlags borderFlags = aBuilder->ShouldSyncDecodeImages()
? PaintBorderFlags::SYNC_DECODE_IMAGES
: PaintBorderFlags();
DrawResult result =
nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, mFrame,
aDirtyRect, buttonRect, aBGFlags);
aDirtyRect, buttonRect, bgFlags);
nsCSSRendering::PaintBoxShadowInner(aPresContext, aRenderingContext,
mFrame, buttonRect, aDirtyRect);
nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, mFrame,
aDirtyRect, buttonRect, context);
result &=
nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, mFrame,
aDirtyRect, buttonRect, context, borderFlags);
return result;
}

View File

@ -39,16 +39,17 @@ public:
nsDisplayList* aBackground, nsDisplayList* aForeground);
void PaintOutlineAndFocusBorders(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
const nsRect& aRect);
DrawResult PaintOutlineAndFocusBorders(nsDisplayListBuilder* aBuilder,
nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
const nsRect& aRect);
DrawResult PaintBorderAndBackground(nsPresContext* aPresContext,
DrawResult PaintBorderAndBackground(nsDisplayListBuilder* aBuilder,
nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
const nsRect& aRect,
uint32_t aBGFlags);
const nsRect& aRect);
void SetFrame(nsFrame* aFrame, nsPresContext* aPresContext);

View File

@ -46,6 +46,7 @@
#include "mozilla/LookAndFeel.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/unused.h"
#include "gfx2DGlue.h"
#ifdef XP_WIN
#define COMBOBOX_ROLLUP_CONSUME_EVENT 0

View File

@ -128,8 +128,7 @@ nsDisplayFieldSetBorderBackground::Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx)
{
DrawResult result = static_cast<nsFieldSetFrame*>(mFrame)->
PaintBorderBackground(*aCtx, ToReferenceFrame(),
mVisibleRect, aBuilder->GetBackgroundPaintFlags());
PaintBorderBackground(aBuilder, *aCtx, ToReferenceFrame(), mVisibleRect);
nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
}
@ -210,8 +209,11 @@ nsFieldSetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
DrawResult
nsFieldSetFrame::PaintBorderBackground(nsRenderingContext& aRenderingContext,
nsPoint aPt, const nsRect& aDirtyRect, uint32_t aBGFlags)
nsFieldSetFrame::PaintBorderBackground(
nsDisplayListBuilder* aBuilder,
nsRenderingContext& aRenderingContext,
nsPoint aPt,
const nsRect& aDirtyRect)
{
// if the border is smaller than the legend. Move the border down
// to be centered on the legend.
@ -223,9 +225,14 @@ nsFieldSetFrame::PaintBorderBackground(nsRenderingContext& aRenderingContext,
rect += aPt;
nsPresContext* presContext = PresContext();
uint32_t bgFlags = aBuilder->GetBackgroundPaintFlags();
PaintBorderFlags borderFlags = aBuilder->ShouldSyncDecodeImages()
? PaintBorderFlags::SYNC_DECODE_IMAGES
: PaintBorderFlags();
DrawResult result =
nsCSSRendering::PaintBackground(presContext, aRenderingContext, this,
aDirtyRect, rect, aBGFlags);
aDirtyRect, rect, bgFlags);
nsCSSRendering::PaintBoxShadowInner(presContext, aRenderingContext,
this, rect, aDirtyRect);
@ -253,8 +260,9 @@ nsFieldSetFrame::PaintBorderBackground(nsRenderingContext& aRenderingContext,
gfx->Save();
gfx->Clip(NSRectToSnappedRect(clipRect.GetPhysicalRect(wm, rect.Size()),
appUnitsPerDevPixel, *drawTarget));
nsCSSRendering::PaintBorder(presContext, aRenderingContext, this,
aDirtyRect, rect, mStyleContext);
result &=
nsCSSRendering::PaintBorder(presContext, aRenderingContext, this,
aDirtyRect, rect, mStyleContext, borderFlags);
gfx->Restore();
// draw inline-end portion of the block-start side of the border
@ -266,8 +274,9 @@ nsFieldSetFrame::PaintBorderBackground(nsRenderingContext& aRenderingContext,
gfx->Save();
gfx->Clip(NSRectToSnappedRect(clipRect.GetPhysicalRect(wm, rect.Size()),
appUnitsPerDevPixel, *drawTarget));
nsCSSRendering::PaintBorder(presContext, aRenderingContext, this,
aDirtyRect, rect, mStyleContext);
result &=
nsCSSRendering::PaintBorder(presContext, aRenderingContext, this,
aDirtyRect, rect, mStyleContext, borderFlags);
gfx->Restore();
// draw remainder of the border (omitting the block-start side)
@ -278,14 +287,15 @@ nsFieldSetFrame::PaintBorderBackground(nsRenderingContext& aRenderingContext,
gfx->Save();
gfx->Clip(NSRectToSnappedRect(clipRect.GetPhysicalRect(wm, rect.Size()),
appUnitsPerDevPixel, *drawTarget));
nsCSSRendering::PaintBorder(presContext, aRenderingContext, this,
aDirtyRect, rect, mStyleContext);
result &=
nsCSSRendering::PaintBorder(presContext, aRenderingContext, this,
aDirtyRect, rect, mStyleContext, borderFlags);
gfx->Restore();
} else {
nsCSSRendering::PaintBorder(presContext, aRenderingContext, this,
aDirtyRect,
nsRect(aPt, mRect.Size()),
mStyleContext);
result &=
nsCSSRendering::PaintBorder(presContext, aRenderingContext, this,
aDirtyRect, nsRect(aPt, mRect.Size()),
mStyleContext, borderFlags);
}
return result;

View File

@ -50,9 +50,9 @@ public:
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists) override;
DrawResult PaintBorderBackground(nsRenderingContext& aRenderingContext,
nsPoint aPt, const nsRect& aDirtyRect,
uint32_t aBGFlags);
DrawResult PaintBorderBackground(nsDisplayListBuilder* aBuilder,
nsRenderingContext& aRenderingContext,
nsPoint aPt, const nsRect& aDirtyRect);
#ifdef DEBUG
virtual void SetInitialChildList(ChildListID aListID,

View File

@ -34,6 +34,7 @@
using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::image;
NS_IMPL_ISUPPORTS(nsRangeFrame::DummyTouchListener, nsIDOMEventListener)
@ -184,11 +185,39 @@ public:
}
#endif
nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override;
void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion *aInvalidRegion) override;
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override;
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) override;
NS_DISPLAY_DECL_NAME("RangeFocusRing", TYPE_OUTLINE)
};
nsDisplayItemGeometry*
nsDisplayRangeFocusRing::AllocateGeometry(nsDisplayListBuilder* aBuilder)
{
return new nsDisplayItemGenericImageGeometry(this, aBuilder);
}
void
nsDisplayRangeFocusRing::ComputeInvalidationRegion(
nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion* aInvalidRegion)
{
auto geometry =
static_cast<const nsDisplayItemGenericImageGeometry*>(aGeometry);
if (aBuilder->ShouldSyncDecodeImages() &&
geometry->ShouldInvalidateToSyncDecodeImages()) {
bool snap;
aInvalidRegion->Or(*aInvalidRegion, GetBounds(aBuilder, &snap));
}
nsDisplayItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion);
}
nsRect
nsDisplayRangeFocusRing::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
{
@ -213,9 +242,17 @@ nsDisplayRangeFocusRing::Paint(nsDisplayListBuilder* aBuilder,
nsStyleContext* styleContext =
static_cast<nsRangeFrame*>(mFrame)->mOuterFocusStyle;
MOZ_ASSERT(styleContext, "We only exist if mOuterFocusStyle is non-null");
nsCSSRendering::PaintBorder(mFrame->PresContext(), *aCtx, mFrame,
mVisibleRect, GetBounds(aBuilder, &unused),
styleContext);
PaintBorderFlags flags = aBuilder->ShouldSyncDecodeImages()
? PaintBorderFlags::SYNC_DECODE_IMAGES
: PaintBorderFlags();
DrawResult result =
nsCSSRendering::PaintBorder(mFrame->PresContext(), *aCtx, mFrame,
mVisibleRect, GetBounds(aBuilder, &unused),
styleContext, flags);
nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
}
void

View File

@ -5,6 +5,7 @@
/* rendering object for css3 multi-column layout */
#include "mozilla/unused.h"
#include "nsColumnSetFrame.h"
#include "nsCSSRendering.h"
#include "nsDisplayList.h"
@ -136,9 +137,17 @@ nsColumnSetFrame::PaintColumnRule(nsRenderingContext* aCtx,
}
nsRect lineRect(linePt, ruleSize);
nsCSSRendering::PaintBorderWithStyleBorder(presContext, *aCtx, this,
aDirtyRect, lineRect, border, StyleContext(),
skipSides);
// Assert that we're not drawing a border-image here; if we were, we
// couldn't ignore the DrawResult that PaintBorderWithStyleBorder returns.
MOZ_ASSERT(border.mBorderImageSource.GetType() == eStyleImageType_Null);
unused <<
nsCSSRendering::PaintBorderWithStyleBorder(presContext, *aCtx, this,
aDirtyRect, lineRect, border,
StyleContext(),
PaintBorderFlags::SYNC_DECODE_IMAGES,
skipSides);
child = nextSibling;
nextSibling = nextSibling->GetNextSibling();

View File

@ -56,6 +56,7 @@
#include "nsIPercentBSizeObserver.h"
#include "nsStyleStructInlines.h"
#include "FrameLayerBuilder.h"
#include "ImageLayers.h"
#include "nsBidiPresUtils.h"
#include "RubyUtils.h"
@ -1901,6 +1902,39 @@ CheckForApzAwareEventHandlers(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
}
}
/**
* True if aDescendant participates the context aAncestor participating.
*/
static bool
Participate3DContextFrame(nsIFrame* aAncestor, nsIFrame* aDescendant) {
MOZ_ASSERT(aAncestor != aDescendant);
MOZ_ASSERT(aAncestor->Extend3DContext());
nsIFrame* frame;
for (frame = nsLayoutUtils::GetCrossDocParentFrame(aDescendant);
frame && aAncestor != frame;
frame = nsLayoutUtils::GetCrossDocParentFrame(frame)) {
if (!frame->Extend3DContext()) {
return false;
}
}
MOZ_ASSERT(frame == aAncestor);
return true;
}
static void
WrapSeparatorTransform(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsRect& aDirtyRect,
nsDisplayList* aSource, nsDisplayList* aTarget,
int aIndex) {
if (!aSource->IsEmpty()) {
nsDisplayTransform *sepIdItem =
new (aBuilder) nsDisplayTransform(aBuilder, aFrame, aSource,
aDirtyRect, Matrix4x4(), aIndex);
sepIdItem->SetNoExtendContext();
aTarget->AppendToTop(sepIdItem);
}
}
void
nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
@ -2160,6 +2194,36 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
* we find all the correct children.
*/
if (isTransformed && !resultList.IsEmpty()) {
if (!resultList.IsEmpty() && Extend3DContext()) {
// Install dummy nsDisplayTransform as a leaf containing
// descendants not participating this 3D rendering context.
nsDisplayList nonparticipants;
nsDisplayList participants;
int index = 1;
while (nsDisplayItem* item = resultList.RemoveBottom()) {
if (item->GetType() == nsDisplayItem::TYPE_TRANSFORM &&
Participate3DContextFrame(this, item->Frame())) {
// The frame of this item participates the same 3D context.
WrapSeparatorTransform(aBuilder, this, dirtyRect,
&nonparticipants, &participants, index++);
participants.AppendToTop(item);
} else {
// The frame of the item doesn't participate the current
// context, or has no transform.
//
// For items participating but not transformed, they are add
// to nonparticipants to get a separator layer for handling
// clips, if there is, on an intermediate surface.
// \see ContainerLayer::DefaultComputeEffectiveTransforms().
nonparticipants.AppendToTop(item);
}
}
WrapSeparatorTransform(aBuilder, this, dirtyRect,
&nonparticipants, &participants, index++);
resultList.AppendToTop(&participants);
}
// Restore clip state now so nsDisplayTransform is clipped properly.
clipState.Restore();
// Revert to the dirtyrect coming in from the parent, without our transform
@ -2176,51 +2240,6 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
nsDisplayTransform *transformItem =
new (aBuilder) nsDisplayTransform(aBuilder, this, &resultList, dirtyRect);
resultList.AppendNewToTop(transformItem);
/*
* Create an additional transform item as a separator layer
* between current and parent's 3D context if necessary.
*
* Separator layers avoid improperly exteding 3D context by
* children.
*/
{
bool needAdditionalTransform = false;
if (Extend3DContext()) {
if (outerReferenceFrame->Extend3DContext()) {
for (nsIFrame *f = nsLayoutUtils::GetCrossDocParentFrame(this);
f && f != outerReferenceFrame && !f->IsTransformed();
f = nsLayoutUtils::GetCrossDocParentFrame(f)) {
if (!f->Extend3DContext()) {
// The first one with transform in it's 3D context chain,
// and it is different 3D context with the outer reference
// frame.
needAdditionalTransform = true;
break;
}
}
}
} else if (outerReferenceFrame->Extend3DContext() &&
outerReferenceFrame != nsLayoutUtils::GetCrossDocParentFrame(this)) {
// The content should be transformed and drawn on a buffer,
// then tranformed and drawn again for outerReferenceFrame.
// So, a separator layer is required.
needAdditionalTransform = true;
}
if (needAdditionalTransform) {
nsRect sepDirty = dirtyRectOutsideTransform;
// The separator item is with ID transform and is out of this
// frame, so it is in the coordination of the outer reference
// frame. Here translate the dirty rect back.
sepDirty.MoveBy(toOuterReferenceFrame);
nsDisplayTransform *sepIdItem =
new (aBuilder) nsDisplayTransform(aBuilder, this, &resultList,
sepDirty,
Matrix4x4(), 1);
sepIdItem->SetNoExtendContext();
resultList.AppendNewToTop(sepIdItem);
}
}
}
/* If we're doing VR rendering, then we need to wrap everything in a nsDisplayVR

View File

@ -15,6 +15,7 @@
#include "mozilla/gfx/Helpers.h"
#include "mozilla/gfx/PathHelpers.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/unused.h"
#include "nsCOMPtr.h"
#include "nsFontMetrics.h"
@ -1337,9 +1338,16 @@ nsImageFrame::DisplayAltFeedback(nsRenderingContext& aRenderingContext,
// Paint the border
if (!isLoading || gIconLoad->mPrefShowLoadingPlaceholder) {
nsRecessedBorder recessedBorder(borderEdgeWidth, PresContext());
nsCSSRendering::PaintBorderWithStyleBorder(PresContext(), aRenderingContext,
this, inner, inner,
recessedBorder, mStyleContext);
// Assert that we're not drawing a border-image here; if we were, we
// couldn't ignore the DrawResult that PaintBorderWithStyleBorder returns.
MOZ_ASSERT(recessedBorder.mBorderImageSource.GetType() == eStyleImageType_Null);
unused <<
nsCSSRendering::PaintBorderWithStyleBorder(PresContext(), aRenderingContext,
this, inner, inner,
recessedBorder, mStyleContext,
PaintBorderFlags::SYNC_DECODE_IMAGES);
}
// Adjust the inner rect to account for the one pixel recessed border,

View File

@ -20,6 +20,7 @@
#include "nsIScriptError.h"
#include "nsIStringBundle.h"
#include "nsContentUtils.h"
#include "ImageLayers.h"
#ifdef ACCESSIBILITY
#include "nsAccessibilityService.h"

Some files were not shown because too many files have changed in this diff Show More