merge mozilla-central to mozilla-inbound. r=merge a=merge

This commit is contained in:
Sebastian Hengst 2017-10-23 23:55:17 +02:00
Родитель b550a1e851 364d36fab2
Коммит 8072106c67
273 изменённых файлов: 6420 добавлений и 1234 удалений

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

@ -21,7 +21,7 @@ nsAccessibleRelation::nsAccessibleRelation(uint32_t aType,
mTargets = do_CreateInstance(NS_ARRAY_CONTRACTID);
Accessible* targetAcc = nullptr;
while ((targetAcc = aRel->Next()))
mTargets->AppendElement(static_cast<nsIAccessible*>(ToXPC(targetAcc)), false);
mTargets->AppendElement(static_cast<nsIAccessible*>(ToXPC(targetAcc)));
}
nsAccessibleRelation::nsAccessibleRelation(uint32_t aType,
@ -31,8 +31,7 @@ nsAccessibleRelation::nsAccessibleRelation(uint32_t aType,
mTargets = do_CreateInstance(NS_ARRAY_CONTRACTID);
for (uint32_t idx = 0; idx < aTargets->Length(); ++idx) {
mTargets->AppendElement(
static_cast<nsIAccessible*>(ToXPC(aTargets->ElementAt(idx))),
false);
static_cast<nsIAccessible*>(ToXPC(aTargets->ElementAt(idx))));
}
}

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

@ -152,7 +152,7 @@ xpcAccessible::GetChildren(nsIArray** aChildren)
uint32_t childCount = IntlGeneric().ChildCount();
for (uint32_t childIdx = 0; childIdx < childCount; childIdx++) {
AccessibleOrProxy child = IntlGeneric().ChildAt(childIdx);
children->AppendElement(static_cast<nsIAccessible*>(ToXPC(child)), false);
children->AppendElement(static_cast<nsIAccessible*>(ToXPC(child)));
}
children.forget(aChildren);
@ -555,7 +555,7 @@ xpcAccessible::GetRelations(nsIArray** aRelations)
uint32_t targets = 0;
relation->GetTargetsCount(&targets);
if (targets)
relations->AppendElement(relation, false);
relations->AppendElement(relation);
}
}

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

@ -540,8 +540,7 @@ xpcAccessibleHyperText::GetSelectionRanges(nsIArray** aRanges)
Intl()->SelectionRanges(&ranges);
uint32_t len = ranges.Length();
for (uint32_t idx = 0; idx < len; idx++)
xpcRanges->AppendElement(new xpcAccessibleTextRange(Move(ranges[idx])),
false);
xpcRanges->AppendElement(new xpcAccessibleTextRange(Move(ranges[idx])));
xpcRanges.forget(aRanges);
return NS_OK;
@ -565,8 +564,7 @@ xpcAccessibleHyperText::GetVisibleRanges(nsIArray** aRanges)
Intl()->VisibleRanges(&ranges);
uint32_t len = ranges.Length();
for (uint32_t idx = 0; idx < len; idx++)
xpcRanges->AppendElement(new xpcAccessibleTextRange(Move(ranges[idx])),
false);
xpcRanges->AppendElement(new xpcAccessibleTextRange(Move(ranges[idx])));
xpcRanges.forget(aRanges);
return NS_OK;

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

@ -34,7 +34,7 @@ xpcAccessibleSelectable::GetSelectedItems(nsIArray** aSelectedItems)
NS_ENSURE_SUCCESS(rv, rv);
for (uint32_t idx = 0; idx < itemCount; idx++)
xpcItems->AppendElement(static_cast<nsIAccessible*>(ToXPC(items[idx])), false);
xpcItems->AppendElement(static_cast<nsIAccessible*>(ToXPC(items[idx])));
NS_ADDREF(*aSelectedItems = xpcItems);
return NS_OK;

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

@ -279,7 +279,7 @@ xpcAccessibleTable::GetSelectedCells(nsIArray** aSelectedCells)
uint32_t totalCount = cellsArray.Length();
for (uint32_t idx = 0; idx < totalCount; idx++) {
Accessible* cell = cellsArray.ElementAt(idx);
selCells->AppendElement(static_cast<nsIAccessible*>(ToXPC(cell)), false);
selCells->AppendElement(static_cast<nsIAccessible*>(ToXPC(cell)));
}
NS_ADDREF(*aSelectedCells = selCells);

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

@ -115,8 +115,7 @@ xpcAccessibleTableCell::GetColumnHeaderCells(nsIArray** aHeaderCells)
NS_ENSURE_TRUE(cells, NS_ERROR_FAILURE);
for (uint32_t idx = 0; idx < headerCells.Length(); idx++) {
cells->AppendElement(static_cast<nsIAccessible*>(ToXPC(headerCells[idx])),
false);
cells->AppendElement(static_cast<nsIAccessible*>(ToXPC(headerCells[idx])));
}
NS_ADDREF(*aHeaderCells = cells);
@ -139,8 +138,7 @@ xpcAccessibleTableCell::GetRowHeaderCells(nsIArray** aHeaderCells)
NS_ENSURE_TRUE(cells, NS_ERROR_FAILURE);
for (uint32_t idx = 0; idx < headerCells.Length(); idx++) {
cells->AppendElement(static_cast<nsIAccessible*>(ToXPC(headerCells[idx])),
false);
cells->AppendElement(static_cast<nsIAccessible*>(ToXPC(headerCells[idx])));
}
NS_ADDREF(*aHeaderCells = cells);

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

@ -87,7 +87,7 @@ xpcAccessibleTextRange::GetEmbeddedChildren(nsIArray** aList)
uint32_t len = objects.Length();
for (uint32_t idx = 0; idx < len; idx++)
xpcList->AppendElement(static_cast<nsIAccessible*>(ToXPC(objects[idx])), false);
xpcList->AppendElement(static_cast<nsIAccessible*>(ToXPC(objects[idx])));
xpcList.forget(aList);

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

@ -204,7 +204,7 @@ pref("extensions.webextensions.themes.icons.buttons", "back,forward,reload,stop,
pref("lightweightThemes.update.enabled", true);
pref("lightweightThemes.getMoreURL", "https://addons.mozilla.org/%LOCALE%/firefox/themes");
pref("lightweightThemes.recommendedThemes", "[{\"id\":\"recommended-1\",\"homepageURL\":\"https://addons.mozilla.org/firefox/addon/a-web-browser-renaissance/\",\"headerURL\":\"resource:///chrome/browser/content/browser/defaultthemes/1.header.jpg\",\"textcolor\":\"#000000\",\"accentcolor\":\"#f2d9b1\",\"iconURL\":\"resource:///chrome/browser/content/browser/defaultthemes/1.icon.jpg\",\"previewURL\":\"resource:///chrome/browser/content/browser/defaultthemes/1.preview.jpg\",\"author\":\"Sean.Martell\",\"version\":\"0\"},{\"id\":\"recommended-2\",\"homepageURL\":\"https://addons.mozilla.org/firefox/addon/space-fantasy/\",\"headerURL\":\"resource:///chrome/browser/content/browser/defaultthemes/2.header.jpg\",\"textcolor\":\"#ffffff\",\"accentcolor\":\"#d9d9d9\",\"iconURL\":\"resource:///chrome/browser/content/browser/defaultthemes/2.icon.jpg\",\"previewURL\":\"resource:///chrome/browser/content/browser/defaultthemes/2.preview.jpg\",\"author\":\"fx5800p\",\"version\":\"1.0\"},{\"id\":\"recommended-4\",\"homepageURL\":\"https://addons.mozilla.org/firefox/addon/pastel-gradient/\",\"headerURL\":\"resource:///chrome/browser/content/browser/defaultthemes/4.header.png\",\"textcolor\":\"#000000\",\"accentcolor\":\"#000000\",\"iconURL\":\"resource:///chrome/browser/content/browser/defaultthemes/4.icon.png\",\"previewURL\":\"resource:///chrome/browser/content/browser/defaultthemes/4.preview.png\",\"author\":\"darrinhenein\",\"version\":\"1.0\"}]");
pref("lightweightThemes.recommendedThemes", "[{\"id\":\"recommended-1\",\"homepageURL\":\"https://addons.mozilla.org/firefox/addon/a-web-browser-renaissance/\",\"headerURL\":\"resource:///chrome/browser/content/browser/defaultthemes/1.header.jpg\",\"textcolor\":\"#000000\",\"accentcolor\":\"#834d29\",\"iconURL\":\"resource:///chrome/browser/content/browser/defaultthemes/1.icon.jpg\",\"previewURL\":\"resource:///chrome/browser/content/browser/defaultthemes/1.preview.jpg\",\"author\":\"Sean.Martell\",\"version\":\"0\"},{\"id\":\"recommended-2\",\"homepageURL\":\"https://addons.mozilla.org/firefox/addon/space-fantasy/\",\"headerURL\":\"resource:///chrome/browser/content/browser/defaultthemes/2.header.jpg\",\"textcolor\":\"#ffffff\",\"accentcolor\":\"#d9d9d9\",\"iconURL\":\"resource:///chrome/browser/content/browser/defaultthemes/2.icon.jpg\",\"previewURL\":\"resource:///chrome/browser/content/browser/defaultthemes/2.preview.jpg\",\"author\":\"fx5800p\",\"version\":\"1.0\"},{\"id\":\"recommended-4\",\"homepageURL\":\"https://addons.mozilla.org/firefox/addon/pastel-gradient/\",\"headerURL\":\"resource:///chrome/browser/content/browser/defaultthemes/4.header.png\",\"textcolor\":\"#000000\",\"accentcolor\":\"#000000\",\"iconURL\":\"resource:///chrome/browser/content/browser/defaultthemes/4.icon.png\",\"previewURL\":\"resource:///chrome/browser/content/browser/defaultthemes/4.preview.png\",\"author\":\"darrinhenein\",\"version\":\"1.0\"}]");
#if defined(MOZ_WIDEVINE_EME)
pref("browser.eme.ui.enabled", true);

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

@ -404,9 +404,6 @@ var PlacesCommandHook = {
*
* @param aBrowser
* a <browser> element.
* @param [optional] aParent
* The folder in which to create a new bookmark if the page loaded in
* aBrowser isn't bookmarked yet, defaults to the unfiled root.
* @param [optional] aShowEditUI
* whether or not to show the edit-bookmark UI for the bookmark item
* @param [optional] aUrl
@ -415,9 +412,9 @@ var PlacesCommandHook = {
* Option to provide a title for a bookmark to use rather than the
* getting the current page's title
*/
async bookmarkPage(aBrowser, aParent, aShowEditUI, aUrl = null, aTitle = null) {
async bookmarkPage(aBrowser, aShowEditUI, aUrl = null, aTitle = null) {
if (PlacesUIUtils.useAsyncTransactions) {
await this._bookmarkPagePT(aBrowser, aParent, aShowEditUI, aUrl, aTitle);
await this._bookmarkPagePT(aBrowser, aShowEditUI, aUrl, aTitle);
return;
}
@ -450,10 +447,9 @@ var PlacesCommandHook = {
StarUI.beginBatch();
}
var parent = aParent !== undefined ?
aParent : PlacesUtils.unfiledBookmarksFolderId;
var descAnno = { name: PlacesUIUtils.DESCRIPTION_ANNO, value: description };
var txn = new PlacesCreateBookmarkTransaction(uri, parent,
var txn = new PlacesCreateBookmarkTransaction(uri,
PlacesUtils.unfiledBookmarksFolderId,
PlacesUtils.bookmarks.DEFAULT_INDEX,
title, null, [descAnno]);
PlacesUtils.transactionManager.doTransaction(txn);
@ -485,16 +481,14 @@ var PlacesCommandHook = {
// TODO: Replace bookmarkPage code with this function once legacy
// transactions are removed.
async _bookmarkPagePT(aBrowser, aParentId, aShowEditUI, aUrl, aTitle) {
async _bookmarkPagePT(aBrowser, aShowEditUI, aUrl, aTitle) {
// If aUrl is provided, we want to bookmark that url rather than the
// the current page
let url = aUrl ? new URL(aUrl) : new URL(aBrowser.currentURI.spec);
let info = await PlacesUtils.bookmarks.fetch({ url });
let isNewBookmark = !info;
if (!info) {
let parentGuid = aParentId !== undefined ?
await PlacesUtils.promiseItemGuid(aParentId) :
PlacesUtils.bookmarks.unfiledGuid;
let parentGuid = PlacesUtils.bookmarks.unfiledGuid;
info = { url, parentGuid };
// Bug 1148838 - Make this code work for full page plugins.
let description = null;
@ -570,14 +564,6 @@ var PlacesCommandHook = {
});
},
/**
* Adds a bookmark to the page loaded in the current tab.
*/
bookmarkCurrentPage: function PCH_bookmarkCurrentPage(aShowEditUI, aParent) {
this.bookmarkPage(gBrowser.selectedBrowser, aParent, aShowEditUI)
.catch(Components.utils.reportError);
},
/**
* Adds a bookmark to the page targeted by a link.
* @param parentId
@ -1821,7 +1807,7 @@ var BookmarkingUI = {
BrowserUtils.setToolbarButtonHeightProperty(this.star);
this.star.setAttribute("animate", "true");
}
PlacesCommandHook.bookmarkCurrentPage(true);
PlacesCommandHook.bookmarkPage(gBrowser.selectedBrowser, true);
}
},

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

@ -58,7 +58,7 @@
#endif
<!-- work-around bug 392512 -->
<command id="Browser:AddBookmarkAs"
oncommand="PlacesCommandHook.bookmarkCurrentPage(true, PlacesUtils.bookmarksMenuFolderId);"/>
oncommand="PlacesCommandHook.bookmarkPage(gBrowser.selectedBrowser, true);"/>
<!-- The command disabled state must be manually updated through
PlacesCommandHook.updateBookmarkAllTabsCommand() -->
<command id="Browser:BookmarkAllTabs"

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

@ -1412,7 +1412,7 @@ nsContextMenu.prototype = {
bookmarkThisPage: function CM_bookmarkThisPage() {
window.top.PlacesCommandHook
.bookmarkPage(this.browser, PlacesUtils.bookmarksMenuFolderId, true)
.bookmarkPage(this.browser, true)
.catch(Components.utils.reportError);
},

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

@ -96,7 +96,7 @@ async function checkBookmarkedPageTitle(url, default_title, overridden_title) {
// Here we test that if we provide a url and a title to bookmark, it will use the
// title provided rather than the one provided by the current page
PlacesCommandHook.bookmarkPage(gBrowser.selectedBrowser, undefined, false, url, overridden_title);
PlacesCommandHook.bookmarkPage(gBrowser.selectedBrowser, false, url, overridden_title);
await promiseBookmark;
let bookmark = await PlacesUtils.bookmarks.fetch({url});
@ -119,7 +119,7 @@ async function checkBookmark(url, expected_title) {
let promiseBookmark = PlacesTestUtils.waitForNotification("onItemAdded",
(id, parentId, index, type, itemUrl) => itemUrl.equals(gBrowser.selectedBrowser.currentURI));
PlacesCommandHook.bookmarkCurrentPage(false);
PlacesCommandHook.bookmarkPage(gBrowser.selectedBrowser);
await promiseBookmark;
let bookmark = await PlacesUtils.bookmarks.fetch({url});

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

@ -29,6 +29,7 @@ add_task(async function() {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla");
await promiseAutocompleteResultPopup("keyword a");
await waitForAutocompleteResultAt(1);
// First item should already be selected
is_selected(0);
@ -43,8 +44,7 @@ add_task(async function() {
await promiseSearchComplete();
is(gURLBar.textValue, "keyword ab", "urlbar should have expected input");
let result = gURLBar.popup.richlistbox.firstChild;
let result = await waitForAutocompleteResultAt(0);
isnot(result, null, "Should have first item");
let uri = NetUtil.newURI(result.getAttribute("url"));
is(uri.spec, PlacesUtils.mozActionURI("keyword", {url: "http://example.com/?q=ab", input: "keyword ab"}), "Expect correct url");

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

@ -541,6 +541,8 @@
command="Browser:RestoreLastSession"/>
<toolbarseparator/>
<toolbaritem id="appMenu-zoom-controls" class="toolbaritem-combined-buttons" closemenu="none">
<!-- Use a spacer, because panel sizing code gets confused when using CSS methods. -->
<spacer/>
<label value="&fullZoom.label;"/>
<toolbarbutton id="appMenu-zoomReduce-button"
class="subviewbutton subviewbutton-iconic"
@ -565,6 +567,8 @@
</toolbaritem>
<toolbarseparator/>
<toolbaritem id="appMenu-edit-controls" class="toolbaritem-combined-buttons" closemenu="none">
<!-- Use a spacer, because panel sizing code gets confused when using CSS methods. -->
<spacer/>
<label value="&editMenu.label;"/>
<toolbarbutton id="appMenu-cut-button"
class="subviewbutton subviewbutton-iconic"

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

@ -1735,7 +1735,7 @@ BrowserGlue.prototype = {
// eslint-disable-next-line complexity
_migrateUI: function BG__migrateUI() {
const UI_VERSION = 56;
const UI_VERSION = 57;
const BROWSER_DOCURL = "chrome://browser/content/browser.xul";
let currentUIVersion;
@ -2142,6 +2142,24 @@ BrowserGlue.prototype = {
}
}
if (currentUIVersion < 57) {
// Beginning Firefox 57, the theme accent color is shown as highlight
// on top of tabs. This didn't look too good with the "A Web Browser Renaissance"
// theme, so we're changing its accent color.
let lwthemePrefs = Services.prefs.getBranch("lightweightThemes.");
if (lwthemePrefs.prefHasUserValue("usedThemes")) {
try {
let usedThemes = lwthemePrefs.getStringPref("usedThemes");
usedThemes = JSON.parse(usedThemes);
let renaissanceTheme = usedThemes.find(theme => theme.id == "recommended-1");
if (renaissanceTheme) {
renaissanceTheme.accentcolor = "#834d29";
lwthemePrefs.setStringPref("usedThemes", JSON.stringify(usedThemes));
}
} catch (e) { /* Don't panic if this pref isn't what we expect it to be. */ }
}
}
// Update the migration version.
Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
},

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

@ -44,7 +44,6 @@ ac_add_options --disable-optimize
ac_add_options --disable-warnings-as-errors
# Temporary config settings until we get these working on mingw
ac_add_options --disable-tests
ac_add_options --disable-accessibility # https://sourceforge.net/p/mingw-w64/bugs/648/
# Long story

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

@ -1,5 +1,5 @@
This is the PDF.js project output, https://github.com/mozilla/pdf.js
Current extension version is: 1.9.640
Current extension version is: 1.9.659
Taken from upstream commit: 853db85b
Taken from upstream commit: 3ac4baff

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

@ -101,7 +101,7 @@ function initializeDefaultPreferences() {
"enablePrintAutoRotate": false,
"disablePageMode": false,
"disablePageLabels": false
};
}
var defaultBranch = Services.prefs.getDefaultBranch(PREF_PREFIX + ".");

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

@ -55,7 +55,7 @@ var DEFAULT_PREFERENCES =
"enablePrintAutoRotate": false,
"disablePageMode": false,
"disablePageLabels": false
};
}
var PdfjsChromeUtils = {

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

@ -1990,7 +1990,7 @@ function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
if (worker.destroyed) {
return Promise.reject(new Error('Worker was destroyed'));
}
let apiVersion = '1.9.640';
let apiVersion = '1.9.659';
source.disableAutoFetch = (0, _dom_utils.getDefaultSetting)('disableAutoFetch');
source.disableStream = (0, _dom_utils.getDefaultSetting)('disableStream');
source.chunkedViewerLoading = !!pdfDataRangeTransport;
@ -3311,8 +3311,8 @@ var _UnsupportedManager = function UnsupportedManagerClosure() {
}();
var version, build;
{
exports.version = version = '1.9.640';
exports.build = build = '853db85b';
exports.version = version = '1.9.659';
exports.build = build = '3ac4baff';
}
exports.getDocument = getDocument;
exports.LoopbackPort = LoopbackPort;
@ -5051,8 +5051,8 @@ exports.SVGGraphics = SVGGraphics;
"use strict";
var pdfjsVersion = '1.9.640';
var pdfjsBuild = '853db85b';
var pdfjsVersion = '1.9.659';
var pdfjsBuild = '3ac4baff';
var pdfjsSharedUtil = __w_pdfjs_require__(0);
var pdfjsDisplayGlobal = __w_pdfjs_require__(13);
var pdfjsDisplayAPI = __w_pdfjs_require__(3);
@ -8177,8 +8177,8 @@ if (!_global_scope2.default.PDFJS) {
}
var PDFJS = _global_scope2.default.PDFJS;
{
PDFJS.version = '1.9.640';
PDFJS.build = '853db85b';
PDFJS.version = '1.9.659';
PDFJS.build = '3ac4baff';
}
PDFJS.pdfBug = false;
if (PDFJS.verbosity !== undefined) {

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

@ -23850,8 +23850,8 @@ exports.PostScriptCompiler = PostScriptCompiler;
"use strict";
var pdfjsVersion = '1.9.640';
var pdfjsBuild = '853db85b';
var pdfjsVersion = '1.9.659';
var pdfjsBuild = '3ac4baff';
var pdfjsCoreWorker = __w_pdfjs_require__(18);
exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
@ -24046,7 +24046,7 @@ var WorkerMessageHandler = {
var cancelXHRs = null;
var WorkerTasks = [];
let apiVersion = docParams.apiVersion;
let workerVersion = '1.9.640';
let workerVersion = '1.9.659';
if (apiVersion !== null && apiVersion !== workerVersion) {
throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`);
}
@ -34390,6 +34390,10 @@ var Type1CharString = function Type1CharStringClosure() {
break;
}
subrNumber = this.stack.pop();
if (!subrs[subrNumber]) {
error = true;
break;
}
error = this.convert(subrs[subrNumber], subrs, seacAnalysisEnabled);
break;
case 11:
@ -34668,6 +34672,12 @@ var Type1Parser = function Type1ParserClosure() {
} while (ch >= 0 && !(0, _util.isSpace)(ch) && !isSpecial(ch));
return token;
},
readCharStrings: function Type1Parser_readCharStrings(bytes, lenIV) {
if (lenIV === -1) {
return bytes;
}
return decrypt(bytes, CHAR_STRS_ENCRYPT_KEY, lenIV);
},
extractFontProgram: function Type1Parser_extractFontProgram() {
var stream = this.stream;
var subrs = [],
@ -34704,7 +34714,7 @@ var Type1Parser = function Type1ParserClosure() {
this.getToken();
data = stream.makeSubStream(stream.pos, length);
lenIV = program.properties.privateData['lenIV'];
encoded = decrypt(data.getBytes(), CHAR_STRS_ENCRYPT_KEY, lenIV);
encoded = this.readCharStrings(data.getBytes(), lenIV);
stream.skip(length);
this.nextChar();
token = this.getToken();
@ -34726,7 +34736,7 @@ var Type1Parser = function Type1ParserClosure() {
this.getToken();
data = stream.makeSubStream(stream.pos, length);
lenIV = program.properties.privateData['lenIV'];
encoded = decrypt(data.getBytes(), CHAR_STRS_ENCRYPT_KEY, lenIV);
encoded = this.readCharStrings(data.getBytes(), lenIV);
stream.skip(length);
this.nextChar();
token = this.getToken();

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

@ -740,24 +740,24 @@ class PDFRenderingQueue {
}
}
getHighestPriority(visible, views, scrolledDown) {
var visibleViews = visible.views;
var numVisible = visibleViews.length;
let visibleViews = visible.views;
let numVisible = visibleViews.length;
if (numVisible === 0) {
return false;
}
for (var i = 0; i < numVisible; ++i) {
var view = visibleViews[i].view;
for (let i = 0; i < numVisible; ++i) {
let view = visibleViews[i].view;
if (!this.isViewFinished(view)) {
return view;
}
}
if (scrolledDown) {
var nextPageIndex = visible.last.id;
let nextPageIndex = visible.last.id;
if (views[nextPageIndex] && !this.isViewFinished(views[nextPageIndex])) {
return views[nextPageIndex];
}
} else {
var previousPageIndex = visible.first.id - 2;
let previousPageIndex = visible.first.id - 2;
if (views[previousPageIndex] && !this.isViewFinished(views[previousPageIndex])) {
return views[previousPageIndex];
}
@ -780,7 +780,7 @@ class PDFRenderingQueue {
break;
case RenderingStates.INITIAL:
this.highestPriorityPage = view.renderingId;
var continueRendering = () => {
let continueRendering = () => {
this.renderHighestPriority();
};
view.draw().then(continueRendering, continueRendering);
@ -4723,7 +4723,7 @@ function isDestArraysEqual(firstDest, secondDest) {
if (Object.keys(first).length !== Object.keys(second).length) {
return false;
}
for (var key in first) {
for (let key in first) {
if (!isEntryEqual(first[key], second[key])) {
return false;
}
@ -8038,7 +8038,7 @@ exports.BasePreferences = undefined;
var _ui_utils = __webpack_require__(0);
var defaultPreferences = null;
let defaultPreferences = null;
function getDefaultPreferences() {
if (!defaultPreferences) {
defaultPreferences = Promise.resolve({
@ -8115,8 +8115,8 @@ class BasePreferences {
} else if (value === undefined) {
throw new Error('Set preference: no value is specified.');
}
var valueType = typeof value;
var defaultType = typeof this.defaults[name];
let valueType = typeof value;
let defaultType = typeof this.defaults[name];
if (valueType !== defaultType) {
if (valueType === 'number' && defaultType === 'string') {
value = value.toString();
@ -8134,11 +8134,11 @@ class BasePreferences {
}
get(name) {
return this._initializedPromise.then(() => {
var defaultValue = this.defaults[name];
let defaultValue = this.defaults[name];
if (defaultValue === undefined) {
throw new Error(`Get preference: "${name}" is undefined.`);
} else {
var prefValue = this.prefs[name];
let prefValue = this.prefs[name];
if (prefValue !== undefined) {
return prefValue;
}
@ -8168,24 +8168,24 @@ var _app = __webpack_require__(4);
var _pdfjsLib = __webpack_require__(1);
function composePage(pdfDocument, pageNumber, size, printContainer) {
var canvas = document.createElement('canvas');
var PRINT_RESOLUTION = 150;
var PRINT_UNITS = PRINT_RESOLUTION / 72.0;
let canvas = document.createElement('canvas');
const PRINT_RESOLUTION = 150;
const PRINT_UNITS = PRINT_RESOLUTION / 72.0;
canvas.width = Math.floor(size.width * PRINT_UNITS);
canvas.height = Math.floor(size.height * PRINT_UNITS);
canvas.style.width = Math.floor(size.width * _ui_utils.CSS_UNITS) + 'px';
canvas.style.height = Math.floor(size.height * _ui_utils.CSS_UNITS) + 'px';
var canvasWrapper = document.createElement('div');
let canvasWrapper = document.createElement('div');
canvasWrapper.appendChild(canvas);
printContainer.appendChild(canvasWrapper);
canvas.mozPrintCallback = function (obj) {
var ctx = obj.context;
let ctx = obj.context;
ctx.save();
ctx.fillStyle = 'rgb(255, 255, 255)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.restore();
pdfDocument.getPage(pageNumber).then(function (pdfPage) {
var renderContext = {
let renderContext = {
canvasContext: ctx,
transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0],
viewport: pdfPage.getViewport(1, size.rotation),
@ -8211,11 +8211,11 @@ function FirefoxPrintService(pdfDocument, pagesOverview, printContainer) {
}
FirefoxPrintService.prototype = {
layout() {
var pdfDocument = this.pdfDocument;
var printContainer = this.printContainer;
var body = document.querySelector('body');
let pdfDocument = this.pdfDocument;
let printContainer = this.printContainer;
let body = document.querySelector('body');
body.setAttribute('data-pdfjsprinting', true);
for (var i = 0, ii = this.pagesOverview.length; i < ii; ++i) {
for (let i = 0, ii = this.pagesOverview.length; i < ii; ++i) {
composePage(pdfDocument, i + 1, this.pagesOverview[i], printContainer);
}
},
@ -8225,8 +8225,8 @@ FirefoxPrintService.prototype = {
};
_app.PDFPrintServiceFactory.instance = {
get supportsPrinting() {
var canvas = document.createElement('canvas');
var value = 'mozPrintCallback' in canvas;
let canvas = document.createElement('canvas');
let value = 'mozPrintCallback' in canvas;
return (0, _pdfjsLib.shadow)(this, 'supportsPrinting', value);
},
createPrintService(pdfDocument, pagesOverview, printContainer) {

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

@ -708,8 +708,6 @@ you can use these alternative items. Otherwise, their values should be empty. -
<!ENTITY pageStylePersistentOnly.label "Basic Page Style">
<!ENTITY pageStylePersistentOnly.accesskey "b">
<!ENTITY pageReportIcon.tooltip "Change pop-up blocking settings for this website">
<!ENTITY allowPopups.accesskey "p">
<!-- On Windows we use the term "Options" to describe settings, but
on Linux and Mac OS X we use "Preferences" - carry that distinction

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

@ -20,8 +20,8 @@
padding-inline-start: 14px;
}
photonpanelmultiview .toolbaritem-combined-buttons > label {
padding-inline-start: 42px; /* 18px toolbarbutton padding + 16px icon + 8px label padding start */
photonpanelmultiview .toolbaritem-combined-buttons > spacer {
width: 42px; /* 18px toolbarbutton padding + 16px icon + 8px label padding start */
}
#appMenu-addon-banners > .addon-banner-item,

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

@ -90,8 +90,8 @@
background-position: center;
width: 24px;
height: 24px;
margin-left: 8px;
margin-right: 8px;
margin-left: 7px;
margin-right: 7px;
position: relative;
/* Need to ensure this gets positioned on top of the position:relative #navigator-toolbox
* in case the dark/light themes give that item a background. */

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

@ -1442,7 +1442,10 @@ photonpanelmultiview .toolbaritem-combined-buttons > label {
-moz-box-flex: 1;
font: menu;
margin: 0;
padding-inline-start: 36px; /* 12px toolbarbutton padding + 16px icon + 8px label padding start */
}
photonpanelmultiview .toolbaritem-combined-buttons > spacer {
width: 36px; /* 12px toolbarbutton padding + 16px icon + 8px label padding start */
}
photonpanelmultiview .PanelUI-subView .toolbaritem-combined-buttons > .subviewbutton {

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

@ -0,0 +1,7 @@
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path fill="context-fill" d="M12 0H4a2 2 0 0 0-2 2v2a1 1 0 0 0 1 1 1 1 0 0 0 1-1V2.5a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 .5.5v10a.5.5 0 0 1-.5.5h-7a.5.5 0 0 1-.5-.5V11a1 1 0 0 0-1-1 1 1 0 0 0-1 1v3a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zM9 15H7v-1h2z"/>
<path fill="context-fill" d="M5.146 10.146a.5.5 0 1 0 .707.707l3-3a.5.5 0 0 0 0-.708l-3-3a.5.5 0 0 0-.707.707L7.293 7H.5a.5.5 0 0 0 0 1h6.793z"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 708 B

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

@ -169,6 +169,7 @@
skin/classic/browser/reload-to-stop.svg (../shared/icons/reload-to-stop.svg)
skin/classic/browser/save.svg (../shared/icons/save.svg)
skin/classic/browser/search-glass.svg (../shared/icons/search-glass.svg)
skin/classic/browser/send-to-device.svg (../shared/icons/send-to-device.svg)
skin/classic/browser/settings.svg (../shared/icons/settings.svg)
skin/classic/browser/sidebars.svg (../shared/icons/sidebars.svg)
skin/classic/browser/sidebars-right.svg (../shared/icons/sidebars-right.svg)

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

@ -119,7 +119,12 @@
#pageAction-panel-sendToDevice,
#pageAction-urlbar-sendToDevice {
list-style-image: url("chrome://browser/skin/device-mobile.svg");
list-style-image: url("chrome://browser/skin/send-to-device.svg");
}
#pageAction-panel-sendToDevice:-moz-locale-dir(rtl) > .toolbarbutton-icon,
#pageAction-urlbar-sendToDevice:-moz-locale-dir(rtl) {
transform: scaleX(-1);
}
.pageAction-sendToDevice-device[clientType=mobile] {
@ -343,12 +348,6 @@
fill-opacity: 1;
}
/* Blocked popup icon */
#page-report-button {
list-style-image: url(chrome://browser/skin/notification-icons/popup.svg);
}
/* Zoom button */
#urlbar-zoom-button {

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

@ -1,7 +1,7 @@
<!-- 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/. -->
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="context-fill">
<path d="M13.917 7C13.44 4.162 10.973 2 8 2 4.686 2 2 4.686 2 8s2.686 6 6 6c2.22 0 4.16-1.207 5.197-3H12c-.912 1.214-2.364 2-4 2-2.76 0-5-2.24-5-5s2.24-5 5-5c2.42 0 4.437 1.718 4.9 4h1.017z"/>
<path d="M14 1L8 7h6V1zm-1 1L9 6h4V2z" fill-rule="evenodd"/>
</svg>

До

Ширина:  |  Высота:  |  Размер: 565 B

После

Ширина:  |  Высота:  |  Размер: 585 B

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

@ -6848,7 +6848,7 @@ nsDocShell::RefreshURI(nsIURI* aURI, int32_t aDelay, bool aRepeat,
if (busyFlags & BUSY_FLAGS_BUSY || (!mIsActive && mDisableMetaRefreshWhenInactive)) {
// We don't want to create the timer right now. Instead queue up the request
// and trigger the timer in EndPageLoad() or whenever we become active.
mRefreshURIList->AppendElement(refreshTimer, /*weak =*/ false);
mRefreshURIList->AppendElement(refreshTimer);
} else {
// There is no page loading going on right now. Create the
// timer and fire it right away.
@ -6860,7 +6860,7 @@ nsDocShell::RefreshURI(nsIURI* aURI, int32_t aDelay, bool aRepeat,
NS_NewTimerWithCallback(refreshTimer, aDelay, nsITimer::TYPE_ONE_SHOT,
win->TabGroup()->EventTargetFor(TaskCategory::Network)));
mRefreshURIList->AppendElement(timer, /*weak =*/ false); // owning timer ref
mRefreshURIList->AppendElement(timer); // owning timer ref
}
return NS_OK;
}
@ -7287,7 +7287,7 @@ nsDocShell::SuspendRefreshURIs()
NS_ASSERTION(rt,
"RefreshURIList timer callbacks should only be RefreshTimer objects");
mRefreshURIList->ReplaceElementAt(rt, i, /*weak =*/ false);
mRefreshURIList->ReplaceElementAt(rt, i);
}
}
@ -7352,7 +7352,7 @@ nsDocShell::RefreshURIFromQueue()
// its corresponding timer object, so that in case another
// load comes through before the timer can go off, the timer will
// get cancelled in CancelRefreshURITimer()
mRefreshURIList->ReplaceElementAt(timer, n, /*weak =*/ false);
mRefreshURIList->ReplaceElementAt(timer, n);
}
}
}

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

@ -256,7 +256,7 @@ ContentPermissionType::GetOptions(nsIArray** aOptions)
rv = isupportsString->SetData(mOptions[i]);
NS_ENSURE_SUCCESS(rv, rv);
rv = options->AppendElement(isupportsString, false);
rv = options->AppendElement(isupportsString);
NS_ENSURE_SUCCESS(rv, rv);
}
@ -276,7 +276,7 @@ nsContentPermissionUtils::ConvertPermissionRequestToArray(nsTArray<PermissionReq
new ContentPermissionType(aSrcArray[i].type(),
aSrcArray[i].access(),
aSrcArray[i].options());
aDesArray->AppendElement(cpt, false);
aDesArray->AppendElement(cpt);
}
return len;
}
@ -341,7 +341,7 @@ nsContentPermissionUtils::CreatePermissionArray(const nsACString& aType,
RefPtr<ContentPermissionType> permType = new ContentPermissionType(aType,
aAccess,
aOptions);
types->AppendElement(permType, false);
types->AppendElement(permType);
types.forget(aTypesArray);
return NS_OK;

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

@ -2523,7 +2523,7 @@ nsDOMWindowUtils::AudioDevices(uint16_t aSide, nsIArray** aDevices)
? CubebUtils::Side::Input
: CubebUtils::Side::Output);
for (auto device: collection) {
devices->AppendElement(device, false);
devices->AppendElement(device);
}
devices.forget(aDevices);

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

@ -2374,6 +2374,16 @@ public:
return inner && inner->IsCurrentInnerWindow() && inner->GetDoc() == this;
}
/**
* Returns whether this document should perform image loads.
*/
bool ShouldLoadImages() const
{
// We check IsBeingUsedAsImage() so that SVG documents loaded as
// images can themselves have data: URL image references.
return IsCurrentActiveDocument() || IsBeingUsedAsImage();
}
/**
* Register/Unregister the ActivityObserver into mActivityObservers to listen
* the document's activity changes such as OnPageHide, visibility, activity.

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

@ -432,7 +432,7 @@ nsScriptErrorBase::GetNotes(nsIArray** aNotes)
uint32_t len = mNotes.Length();
for (uint32_t i = 0; i < len; i++)
array->AppendElement(mNotes[i], false);
array->AppendElement(mNotes[i]);
array.forget(aNotes);
return NS_OK;

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

@ -968,7 +968,7 @@ DataTransfer::GetTransferables(nsILoadContext* aLoadContext)
for (uint32_t i = 0; i < count; i++) {
nsCOMPtr<nsITransferable> transferable = GetTransferable(i, aLoadContext);
if (transferable) {
transArray->AppendElement(transferable, /*weak =*/ false);
transArray->AppendElement(transferable);
}
}

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

@ -397,7 +397,7 @@ EventListenerService::NotifyAboutMainThreadListenerChangeInternal(dom::EventTarg
mPendingListenerChangesSet.LookupForAdd(aTarget).OrInsert(
[this, aTarget] () {
EventListenerChange* c = new EventListenerChange(aTarget);
mPendingListenerChanges->AppendElement(c, false);
mPendingListenerChanges->AppendElement(c);
return c;
});
changes->AddChangedListenerName(aName);

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

@ -1917,8 +1917,7 @@ HTMLFormElement::CheckFormValidity(nsIMutableArray* aInvalidElements) const
// Add all unhandled invalid controls to aInvalidElements if the caller
// requested them.
if (defaultAction && aInvalidElements) {
aInvalidElements->AppendElement(ToSupports(sortedControls[i]),
false);
aInvalidElements->AppendElement(ToSupports(sortedControls[i]));
}
}
}

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

@ -431,7 +431,7 @@ HTMLImageElement::AfterMaybeChangeAttr(int32_t aNamespaceID, nsAtom* aName,
mSrcTriggeringPrincipal);
}
QueueImageLoadTask(true);
} else if (aNotify && OwnerDoc()->IsCurrentActiveDocument()) {
} else if (aNotify && OwnerDoc()->ShouldLoadImages()) {
// If aNotify is false, we are coming from the parser or some such place;
// we'll get bound after all the attributes have been set, so we'll do the
// sync image load from BindToTree. Skip the LoadImage call in that case.
@ -491,7 +491,7 @@ HTMLImageElement::AfterMaybeChangeAttr(int32_t aNamespaceID, nsAtom* aName,
// per spec, full selection runs when this changes, even though
// it doesn't directly affect the source selection
QueueImageLoadTask(true);
} else if (OwnerDoc()->IsCurrentActiveDocument()) {
} else if (OwnerDoc()->ShouldLoadImages()) {
// Bug 1076583 - We still use the older synchronous algorithm in
// non-responsive mode. Force a new load of the image with the
// new cross origin policy
@ -608,7 +608,7 @@ HTMLImageElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
// Otherwise MaybeLoadImage may run later when someone has reenabled
// loading.
if (LoadingEnabled() &&
OwnerDoc()->IsCurrentActiveDocument()) {
OwnerDoc()->ShouldLoadImages()) {
nsContentUtils::AddScriptRunner(
NewRunnableMethod<bool>("dom::HTMLImageElement::MaybeLoadImage",
this,
@ -830,7 +830,7 @@ HTMLImageElement::CopyInnerTo(Element* aDest, bool aPreallocateChildren)
// reaches a stable state.
if (!dest->InResponsiveMode() &&
dest->HasAttr(kNameSpaceID_None, nsGkAtoms::src) &&
dest->OwnerDoc()->IsCurrentActiveDocument()) {
dest->OwnerDoc()->ShouldLoadImages()) {
// Mark channel as urgent-start before load image if the image load is
// initaiated by a user interaction.
mUseUrgentStartForChannel = EventStateManager::IsHandlingUserInput();
@ -911,7 +911,7 @@ HTMLImageElement::QueueImageLoadTask(bool aAlwaysLoad)
{
// If loading is temporarily disabled, we don't want to queue tasks
// that may then run when loading is re-enabled.
if (!LoadingEnabled() || !this->OwnerDoc()->IsCurrentActiveDocument()) {
if (!LoadingEnabled() || !this->OwnerDoc()->ShouldLoadImages()) {
return;
}

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

@ -1653,7 +1653,7 @@ HTMLMediaElement::GetSrcObject() const
void
HTMLMediaElement::SetSrcObject(DOMMediaStream& aValue)
{
SetMozSrcObject(&aValue);
SetSrcObject(&aValue);
}
void
@ -1664,31 +1664,6 @@ HTMLMediaElement::SetSrcObject(DOMMediaStream* aValue)
DoLoad();
}
// TODO: Remove prefixed versions soon (1183495)
already_AddRefed<DOMMediaStream>
HTMLMediaElement::GetMozSrcObject() const
{
NS_ASSERTION(!mSrcAttrStream || mSrcAttrStream->GetPlaybackStream(),
"MediaStream should have been set up properly");
RefPtr<DOMMediaStream> stream = mSrcAttrStream;
return stream.forget();
}
void
HTMLMediaElement::SetMozSrcObject(DOMMediaStream& aValue)
{
SetMozSrcObject(&aValue);
}
void
HTMLMediaElement::SetMozSrcObject(DOMMediaStream* aValue)
{
mSrcAttrStream = aValue;
UpdateAudioChannelPlayingState();
DoLoad();
}
NS_IMETHODIMP HTMLMediaElement::GetMozAutoplayEnabled(bool *aAutoplayEnabled)
{
*aAutoplayEnabled = mAutoplayEnabled;
@ -2682,6 +2657,12 @@ HTMLMediaElement::FastSeek(double aTime, ErrorResult& aRv)
already_AddRefed<Promise>
HTMLMediaElement::SeekToNextFrame(ErrorResult& aRv)
{
if (mSeekDOMPromise) {
// We can't perform NextFrameSeek while seek is already in action.
// Just return the pending seek promise.
return do_AddRef(mSeekDOMPromise);
}
/* This will cause JIT code to be kept around longer, to help performance
* when using SeekToNextFrame to iterate through every frame of a video.
*/

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

@ -644,11 +644,6 @@ public:
void SetSrcObject(DOMMediaStream& aValue);
void SetSrcObject(DOMMediaStream* aValue);
// TODO: remove prefixed versions soon (1183495).
already_AddRefed<DOMMediaStream> GetMozSrcObject() const;
void SetMozSrcObject(DOMMediaStream& aValue);
void SetMozSrcObject(DOMMediaStream* aValue);
bool MozPreservesPitch() const
{
return mPreservesPitch;

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

@ -170,7 +170,7 @@ nsIConstraintValidation::ReportValidity()
nsCOMPtr<nsIMutableArray> invalidElements =
do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
invalidElements->AppendElement(content, false);
invalidElements->AppendElement(content);
NS_ENSURE_SUCCESS(rv, true);
nsCOMPtr<nsISupports> inst;

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

@ -245,6 +245,7 @@ const char* mozilla::dom::ContentPrefs::gInitPrefs[] = {
"toolkit.telemetry.minSubsessionLength",
"toolkit.telemetry.scheduler.idleTickInterval",
"toolkit.telemetry.scheduler.tickInterval",
"toolkit.telemetry.testing.overridePreRelease",
"toolkit.telemetry.unified",
"ui.key.menuAccessKeyFocuses",
"ui.popup.disable_autohide",

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

@ -2518,7 +2518,7 @@ MediaManager::GetUserMedia(nsPIDOMWindowInner* aWindow,
nsCOMPtr<nsIMutableArray> devicesCopy = nsArray::Create(); // before we give up devices below
if (!askPermission) {
for (auto& device : **devices) {
nsresult rv = devicesCopy->AppendElement(device, /*weak =*/ false);
nsresult rv = devicesCopy->AppendElement(device);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
@ -3317,7 +3317,7 @@ MediaManager::GetActiveMediaCaptureWindows(nsIArray** aArray)
if (winListener->CapturingVideo() || winListener->CapturingAudio() ||
winListener->CapturingScreen() || winListener->CapturingWindow() ||
winListener->CapturingApplication()) {
array->AppendElement(window, /*weak =*/ false);
array->AppendElement(window);
}
}

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

@ -294,14 +294,14 @@ GMPContentChild::RecvPChromiumCDMConstructor(PChromiumCDMChild* aActor)
// Try to create older version 8 CDM.
cdm::Host_8* host8 = child;
err = mGMPChild->GetAPI(CHROMIUM_CDM_API_BACKWARD_COMPAT, host8, &cdm);
cdm =
new ChromiumCDM8BackwardsCompat(
host9,
static_cast<cdm::ContentDecryptionModule_8*>(cdm));
if (err != GMPNoErr) {
NS_WARNING("GMPGetAPI call failed trying to get CDM.");
return IPC_FAIL_NO_REASON(this);
}
cdm =
new ChromiumCDM8BackwardsCompat(
host9,
static_cast<cdm::ContentDecryptionModule_8*>(cdm));
}
child->Init(static_cast<cdm::ContentDecryptionModule_9*>(cdm));

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

@ -11,7 +11,7 @@ navigator.mozGetUserMedia({audio: true, fake: true}, function(stream) {
document.querySelector("html").className = "";
}
})
testAudio.mozSrcObject = stream;
testAudio.srcObject = stream;
testAudio.play();
}, function(err) {
// Don't go orange if we can't get an audio input stream,

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

@ -106,7 +106,7 @@ function startTest() {
}
var steps = 0;
element.mozSrcObject = stream;
element.srcObject = stream;
element.onplaying = onplaying;
element.onended = onended;
element.play();

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

@ -49,9 +49,7 @@ var doTest = srcObject => new Promise(resolve => {
b.play();
});
// TODO: remove prefixed version soon (1183495).
var doTests = () => doTest("srcObject").then(() => doTest("mozSrcObject"))
var doTests = () => doTest("srcObject")
.catch(e => ok(false, "Unexpected error: " + e))
.then(() => SimpleTest.finish())
.catch(e => ok(false, "Coding error: " + e));

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

@ -69,7 +69,7 @@ scriptsReady
oscThroughMediaElement.connect(msDest);
oscThroughAudioDestinationNode.connect(ac.destination);
acTone.mozSrcObject = msDest.stream;
acTone.srcObject = msDest.stream;
getSineWaveFile(10000, 10, function(blob) {
wavtone.src = URL.createObjectURL(blob);

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

@ -53,7 +53,7 @@ pc2.onicecandidate = e => {
var v1, v2;
var delivered = new Promise(resolve => {
pc2.onaddstream = e => {
v2.mozSrcObject = e.stream;
v2.srcObject = e.stream;
resolve(e.stream);
};
});
@ -66,7 +66,7 @@ runNetworkTest(function() {
// not testing legacy gUM here
navigator.mediaDevices.getUserMedia({ video: true, audio: true })
.then(stream => pc1.addStream(v1.mozSrcObject = stream))
.then(stream => pc1.addStream(v1.srcObject = stream))
.then(() => pcall(pc1, pc1.createOffer))
.then(offer => pcall(pc1, pc1.setLocalDescription, offer))
.then(() => pcall(pc2, pc2.setRemoteDescription, pc1.localDescription))
@ -75,7 +75,7 @@ runNetworkTest(function() {
.then(() => pcall(pc1, pc1.setRemoteDescription, pc2.localDescription))
.then(() => delivered)
// .then(() => canPlayThrough) // why doesn't this fire?
.then(() => waitUntil(() => v2.currentTime > 0 && v2.mozSrcObject.currentTime > 0))
.then(() => waitUntil(() => v2.currentTime > 0 && v2.srcObject.currentTime > 0))
.then(() => ok(v2.currentTime > 0, "v2.currentTime is moving (" + v2.currentTime + ")"))
.then(() => ok(true, "Connected."))
.then(() => pcall(pc1, pc1.getStats, null))

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

@ -192,7 +192,7 @@ PaymentDetailsModifier::Create(const IPCPaymentDetailsModifier& aIPCModifier,
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = items->AppendElement(additionalItem, false);
rv = items->AppendElement(additionalItem);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -361,7 +361,7 @@ PaymentDetails::Create(const IPCPaymentDetails& aIPCDetails,
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = items->AppendElement(item, false);
rv = items->AppendElement(item);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -379,7 +379,7 @@ PaymentDetails::Create(const IPCPaymentDetails& aIPCDetails,
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = options->AppendElement(option, false);
rv = options->AppendElement(option);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -397,7 +397,7 @@ PaymentDetails::Create(const IPCPaymentDetails& aIPCDetails,
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = detailsModifiers->AppendElement(detailsModifier, false);
rv = detailsModifiers->AppendElement(detailsModifier);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}

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

@ -47,7 +47,7 @@ PaymentRequestParent::RecvRequestPayment(const IPCPaymentActionRequest& aRequest
if (NS_WARN_IF(NS_FAILED(rv))) {
return IPC_FAIL_NO_REASON(this);
}
rv = methodData->AppendElement(method, false);
rv = methodData->AppendElement(method);
if (NS_WARN_IF(NS_FAILED(rv))) {
return IPC_FAIL_NO_REASON(this);
}

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

@ -184,7 +184,7 @@ PresentationDeviceManager::GetAvailableDevices(nsIArray* aPresentationUrls, nsIA
nsCOMPtr<nsIMutableArray> devices = do_CreateInstance(NS_ARRAY_CONTRACTID);
for (uint32_t i = 0; i < mDevices.Length(); ++i) {
if (presentationUrls.IsEmpty()) {
devices->AppendElement(mDevices[i], false);
devices->AppendElement(mDevices[i]);
continue;
}
@ -193,7 +193,7 @@ PresentationDeviceManager::GetAvailableDevices(nsIArray* aPresentationUrls, nsIA
if (NS_SUCCEEDED(mDevices[i]->IsRequestedUrlSupported(presentationUrls[j],
&isSupported)) &&
isSupported) {
devices->AppendElement(mDevices[i], false);
devices->AppendElement(mDevices[i]);
break;
}
}

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

@ -82,7 +82,7 @@ ConvertURLArrayHelper(const nsTArray<nsString>& aUrls, nsIArray** aResult)
return rv;
}
rv = urls->AppendElement(isupportsString, false);
rv = urls->AppendElement(isupportsString);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}

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

@ -174,7 +174,7 @@ TCPPresentationChannelDescription::GetTcpAddress(nsIArray** aRetVal)
}
address->SetData(mAddress);
array->AppendElement(address, false);
array->AppendElement(address);
array.forget(aRetVal);
return NS_OK;

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

@ -111,8 +111,6 @@ partial interface HTMLMediaElement {
void mozDumpDebugInfo();
attribute MediaStream? srcObject;
// TODO: remove prefixed version soon (1183495).
attribute MediaStream? mozSrcObject;
attribute boolean mozPreservesPitch;
readonly attribute boolean mozAutoplayEnabled;

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

@ -3734,7 +3734,7 @@ ServiceWorkerManager::GetAllRegistrations(nsIArray** aResult)
continue;
}
array->AppendElement(reg, false);
array->AppendElement(reg);
}
}

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

@ -1550,8 +1550,17 @@ XMLHttpRequestMainThread::Open(const nsACString& aMethod,
} else if (responsibleDocument) {
baseURI = responsibleDocument->GetBaseURI();
}
// Use the responsible document's encoding for the URL if we have one,
// except for dedicated workers. Use UTF-8 otherwise.
NotNull<const Encoding*> originCharset = UTF_8_ENCODING;
if (responsibleDocument &&
responsibleDocument->NodePrincipal() == mPrincipal) {
originCharset = responsibleDocument->GetDocumentCharacterSet();
}
nsCOMPtr<nsIURI> parsedURL;
rv = NS_NewURI(getter_AddRefs(parsedURL), aUrl, nullptr, baseURI);
rv = NS_NewURI(getter_AddRefs(parsedURL), aUrl, originCharset, baseURI);
if (NS_FAILED(rv)) {
if (rv == NS_ERROR_MALFORMED_URI) {
return NS_ERROR_DOM_MALFORMED_URI;

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

@ -1402,7 +1402,7 @@ nsXULTemplateBuilder::LoadDataSourceUrls(nsIDocument* aDocument,
getter_AddRefs(dsnode));
if (dsnode)
uriList->AppendElement(dsnode, false);
uriList->AppendElement(dsnode);
continue;
}
@ -1420,7 +1420,7 @@ nsXULTemplateBuilder::LoadDataSourceUrls(nsIDocument* aDocument,
if (!isTrusted && NS_FAILED(docPrincipal->CheckMayLoad(uri, true, false)))
continue;
uriList->AppendElement(uri, false);
uriList->AppendElement(uri);
}
nsCOMPtr<nsIDOMNode> rootNode = do_QueryInterface(mRoot);

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

@ -2765,7 +2765,7 @@ HTMLEditor::GetLinkedObjects(nsIArray** aNodeList)
nsCOMPtr<nsIURIRefObject> refObject;
rv = NS_NewHTMLURIRefObject(getter_AddRefs(refObject), node);
if (NS_SUCCEEDED(rv)) {
nodes->AppendElement(refObject, false);
nodes->AppendElement(refObject);
}
}
iter->Next();
@ -3060,7 +3060,7 @@ HTMLEditor::GetEmbeddedObjects(nsIArray** aNodeList)
(element->IsHTMLElement(nsGkAtoms::body) &&
element->HasAttr(kNameSpaceID_None, nsGkAtoms::background))) {
nsCOMPtr<nsIDOMNode> domNode = do_QueryInterface(node);
nodes->AppendElement(domNode, false);
nodes->AppendElement(domNode);
}
}
iter->Next();

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

@ -175,4 +175,4 @@ Troubleshooting tips:
-------------------------------------------------------------------------------
The version of WebRender currently in the tree is:
7892f5364bc4d35c7a9b42949f0ace4cc54f8b3c
d741f472dd3d6c3441646f7bf4e714c71bea39b7

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

@ -1,6 +1,6 @@
[package]
name = "webrender"
version = "0.52.1"
version = "0.53.0"
authors = ["Glenn Watson <gw@intuitionlibrary.com>"]
license = "MPL-2.0"
repository = "https://github.com/servo/webrender"

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

@ -218,7 +218,11 @@ impl Example for App {
rect: (75, 75).by(100, 100),
repeat: false,
};
let complex = ComplexClipRegion::new((50, 50).to(150, 150), BorderRadius::uniform(20.0));
let complex = ComplexClipRegion::new(
(50, 50).to(150, 150),
BorderRadius::uniform(20.0),
ClipMode::Clip
);
let id = builder.define_clip(None, bounds, vec![complex], Some(mask));
builder.push_clip_id(id);
@ -339,7 +343,7 @@ impl Example for App {
color,
blur_radius,
spread_radius,
simple_border_radius,
BorderRadius::uniform(simple_border_radius),
box_shadow_type,
);
}

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

@ -17,8 +17,8 @@ use std::collections::HashMap;
use std::collections::hash_map::Entry;
use std::sync::Arc;
use std::sync::mpsc::{channel, Receiver, Sender};
use webrender::api::{self, DisplayListBuilder, DocumentId, LayoutSize, PipelineId, RenderApi,
ResourceUpdates};
use webrender::api::{self, DeviceUintRect, DisplayListBuilder, DocumentId, LayoutSize, PipelineId,
RenderApi, ResourceUpdates};
// This example shows how to implement a very basic BlobImageRenderer that can only render
// a checkerboard pattern.
@ -145,7 +145,7 @@ impl api::BlobImageRenderer for CheckerboardRenderer {
.insert(key, Arc::new(deserialize_blob(&cmds[..]).unwrap()));
}
fn update(&mut self, key: api::ImageKey, cmds: api::BlobImageData) {
fn update(&mut self, key: api::ImageKey, cmds: api::BlobImageData, _dirty_rect: Option<DeviceUintRect>) {
// Here, updating is just replacing the current version of the commands with
// the new one (no incremental updates).
self.image_cmds

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

@ -22,12 +22,18 @@ impl Notifier {
}
impl RenderNotifier for Notifier {
fn new_frame_ready(&mut self) {
fn clone(&self) -> Box<RenderNotifier> {
Box::new(Notifier {
window_proxy: self.window_proxy.clone(),
})
}
fn new_frame_ready(&self) {
#[cfg(not(target_os = "android"))]
self.window_proxy.wakeup_event_loop();
}
fn new_scroll_frame_ready(&mut self, _composite_needed: bool) {
fn new_scroll_frame_ready(&self, _composite_needed: bool) {
#[cfg(not(target_os = "android"))]
self.window_proxy.wakeup_event_loop();
}
@ -125,13 +131,11 @@ pub fn main_wrapper(example: &mut Example, options: Option<webrender::RendererOp
};
let size = DeviceUintSize::new(width, height);
let (mut renderer, sender) = webrender::Renderer::new(gl.clone(), opts).unwrap();
let notifier = Box::new(Notifier::new(window.create_window_proxy()));
let (mut renderer, sender) = webrender::Renderer::new(gl.clone(), notifier, opts).unwrap();
let api = sender.create_api();
let document_id = api.add_document(size);
let notifier = Box::new(Notifier::new(window.create_window_proxy()));
renderer.set_render_notifier(notifier);
if let Some(external_image_handler) = example.get_external_image_handler() {
renderer.set_external_image_handler(external_image_handler);
}

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

@ -14,12 +14,15 @@ flat varying vec4 vClipCenter_Radius_BL;
struct BrushPrimitive {
float clip_mode;
float radius;
vec2 radius_tl;
vec2 radius_tr;
vec2 radius_br;
vec2 radius_bl;
};
BrushPrimitive fetch_brush_primitive(int address) {
vec4 data = fetch_from_resource_cache_1(address);
return BrushPrimitive(data.x, data.y);
vec4 data[3] = fetch_from_resource_cache_3(address);
return BrushPrimitive(data[0].x, data[1].xy, data[1].zw, data[2].xy, data[2].zw);
}
void brush_vs(int prim_address, vec4 prim_rect) {
@ -29,11 +32,10 @@ void brush_vs(int prim_address, vec4 prim_rect) {
// Write clip parameters
vClipMode = prim.clip_mode;
vec2 r = vec2(prim.radius);
vClipCenter_Radius_TL = vec4(prim_rect.xy + vec2(r.x, r.y), r);
vClipCenter_Radius_TR = vec4(prim_rect.zy + vec2(-r.x, r.y), r);
vClipCenter_Radius_BR = vec4(prim_rect.zw + vec2(-r.x, -r.y), r);
vClipCenter_Radius_BL = vec4(prim_rect.xw + vec2(r.x, -r.y), r);
vClipCenter_Radius_TL = vec4(prim_rect.xy + prim.radius_tl, prim.radius_tl);
vClipCenter_Radius_TR = vec4(prim_rect.zy + vec2(-prim.radius_tr.x, prim.radius_tr.y), prim.radius_tr);
vClipCenter_Radius_BR = vec4(prim_rect.zw - prim.radius_br, prim.radius_br);
vClipCenter_Radius_BL = vec4(prim_rect.xw + vec2(prim.radius_bl.x, -prim.radius_bl.y), prim.radius_bl);
}
#endif

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

@ -20,16 +20,14 @@ flat varying int vBlurRadius;
in int aBlurRenderTaskAddress;
in int aBlurSourceTaskAddress;
in int aBlurDirection;
in vec4 aBlurRegion;
void main(void) {
RenderTaskData task = fetch_render_task(aBlurRenderTaskAddress);
RenderTaskData src_task = fetch_render_task(aBlurSourceTaskAddress);
vec4 local_rect = task.data0;
vec2 pos = mix(local_rect.xy,
local_rect.xy + local_rect.zw,
aPosition.xy);
vec4 src_rect = src_task.data0;
vec4 target_rect = task.data0;
#if defined WR_FEATURE_COLOR
vec2 texture_size = vec2(textureSize(sCacheRGBA8, 0).xy);
@ -49,12 +47,20 @@ void main(void) {
break;
}
vUvRect = vec4(src_task.data0.xy + vec2(0.5),
src_task.data0.xy + src_task.data0.zw - vec2(0.5));
vUvRect = vec4(src_rect.xy + vec2(0.5),
src_rect.xy + src_rect.zw - vec2(0.5));
vUvRect /= texture_size.xyxy;
vec2 uv0 = src_task.data0.xy / texture_size;
vec2 uv1 = (src_task.data0.xy + src_task.data0.zw) / texture_size;
if (aBlurRegion.z > 0.0) {
vec4 blur_region = aBlurRegion * uDevicePixelRatio;
src_rect = vec4(src_rect.xy + blur_region.xy, blur_region.zw);
target_rect = vec4(target_rect.xy + blur_region.xy, blur_region.zw);
}
vec2 pos = target_rect.xy + target_rect.zw * aPosition.xy;
vec2 uv0 = src_rect.xy / texture_size;
vec2 uv1 = (src_rect.xy + src_rect.zw) / texture_size;
vUv.xy = mix(uv0, uv1, aPosition.xy);
gl_Position = uTransform * vec4(pos, 0.0, 1.0);

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

@ -15,6 +15,7 @@ use util::{lerp, pack_as_float};
#[repr(u8)]
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum BorderCornerInstance {
None,
Single, // Single instance needed - corner styles are same or similar.
Double, // Different corner styles. Draw two instances, one per style.
}
@ -128,8 +129,8 @@ impl NormalBorderHelpers for NormalBorder {
corner: BorderCorner,
border_rect: &LayerRect,
) -> BorderCornerKind {
// If either width is zero, a corner isn't formed.
if width0 == 0.0 || width1 == 0.0 {
// If both widths are zero, a corner isn't formed.
if width0 == 0.0 && width1 == 0.0 {
return BorderCornerKind::None;
}
@ -139,9 +140,13 @@ impl NormalBorderHelpers for NormalBorder {
}
match (edge0.style, edge1.style) {
// If either edge is none or hidden, no corner is needed.
(BorderStyle::None, _) | (_, BorderStyle::None) => BorderCornerKind::None,
(BorderStyle::Hidden, _) | (_, BorderStyle::Hidden) => BorderCornerKind::None,
// If both edges are none or hidden, no corner is needed.
(BorderStyle::None, BorderStyle::None) |
(BorderStyle::None, BorderStyle::Hidden) |
(BorderStyle::Hidden, BorderStyle::None) |
(BorderStyle::Hidden, BorderStyle::Hidden) => {
BorderCornerKind::None
}
// If both borders are solid, we can draw them with a simple rectangle if
// both the colors match and there is no radius.
@ -429,16 +434,19 @@ impl FrameBuilder {
let mut corner_instances = [BorderCornerInstance::Single; 4];
for (i, corner) in corners.iter().enumerate() {
match corner {
&BorderCornerKind::Mask(corner_data, corner_radius, widths, kind) => {
match *corner {
BorderCornerKind::Mask(corner_data, corner_radius, widths, kind) => {
let clip_source =
BorderCornerClipSource::new(corner_data, corner_radius, widths, kind);
extra_clips.push(ClipSource::BorderCorner(clip_source));
}
&BorderCornerKind::Clip(instance_kind) => {
BorderCornerKind::Clip(instance_kind) => {
corner_instances[i] = instance_kind;
}
_ => {}
BorderCornerKind::Solid => {}
BorderCornerKind::None => {
corner_instances[i] = BorderCornerInstance::None;
}
}
}

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

@ -3,14 +3,14 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::{BorderRadius, ComplexClipRegion, DeviceIntRect, ImageMask, ImageRendering, LayerPoint};
use api::{LayerRect, LayerSize, LayerToWorldTransform, LayoutPoint, LayoutVector2D, LocalClip};
use api::{ClipMode, LayerRect, LayerSize};
use api::{LayerToWorldTransform, LayoutPoint, LayoutVector2D, LocalClip};
use border::BorderCornerClipSource;
use ellipse::Ellipse;
use freelist::{FreeList, FreeListHandle, WeakFreeListHandle};
use gpu_cache::{GpuCache, GpuCacheHandle, ToGpuBlocks};
use prim_store::{ClipData, ImageMaskData};
use resource_cache::ResourceCache;
use std::ops::Not;
use util::{extract_inner_rect_safe, TransformedRect};
const MAX_CLIP: f32 = 1000000.0;
@ -61,24 +61,6 @@ impl ClipRegion {
}
}
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum ClipMode {
Clip, // Pixels inside the region are visible.
ClipOut, // Pixels outside the region are visible.
}
impl Not for ClipMode {
type Output = ClipMode;
fn not(self) -> ClipMode {
match self {
ClipMode::Clip => ClipMode::ClipOut,
ClipMode::ClipOut => ClipMode::Clip,
}
}
}
#[derive(Debug)]
pub enum ClipSource {
Rectangle(LayerRect),
@ -105,7 +87,7 @@ impl From<ClipRegion> for ClipSources {
clips.push(ClipSource::RoundedRectangle(
complex.rect,
complex.radii,
ClipMode::Clip,
complex.mode,
));
}

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

@ -9,7 +9,7 @@ use api::{HitTestResult, ImageDisplayItem, ItemRange, LayerPoint, LayerPrimitive
use api::{LayerSize, LayerToScrollTransform, LayerVector2D, LayoutSize, LayoutTransform};
use api::{LocalClip, PipelineId, ScrollClamping, ScrollEventPhase, ScrollLayerState};
use api::{ScrollLocation, ScrollPolicy, ScrollSensitivity, SpecificDisplayItem, StackingContext};
use api::{TileOffset, TransformStyle, WorldPoint};
use api::{ClipMode, TileOffset, TransformStyle, WorldPoint};
use clip::ClipRegion;
use clip_scroll_tree::{ClipScrollTree, ScrollStates};
use euclid::rect;
@ -1151,7 +1151,12 @@ fn try_to_add_rectangle_splitting_on_clip(
let inner_unclipped_rect = match &info.local_clip {
&LocalClip::Rect(_) => return false,
&LocalClip::RoundedRect(_, ref region) => region.get_inner_rect_full(),
&LocalClip::RoundedRect(_, ref region) => {
if region.mode == ClipMode::ClipOut {
return false;
}
region.get_inner_rect_full()
}
};
let inner_unclipped_rect = match inner_unclipped_rect {
Some(rect) => rect,

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

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::{BorderDetails, BorderDisplayItem, BorderRadius, BoxShadowClipMode, BuiltDisplayList};
use api::{ComplexClipRegion, ClipAndScrollInfo, ClipId, ColorF};
use api::{ClipMode, ComplexClipRegion, ClipAndScrollInfo, ClipId, ColorF, LayoutSize};
use api::{DeviceIntPoint, DeviceIntRect, DeviceIntSize, DeviceUintRect, DeviceUintSize};
use api::{ExtendMode, FilterOp, FontInstance, FontRenderMode};
use api::{GlyphInstance, GlyphOptions, GradientStop, HitTestFlags, HitTestItem, HitTestResult};
@ -14,7 +14,7 @@ use api::{ScrollSensitivity, Shadow, TileOffset, TransformStyle};
use api::{WorldPixel, WorldPoint, YuvColorSpace, YuvData, device_length};
use app_units::Au;
use border::ImageBorderSegment;
use clip::{ClipMode, ClipRegion, ClipSource, ClipSources, ClipStore, Contains};
use clip::{ClipRegion, ClipSource, ClipSources, ClipStore, Contains};
use clip_scroll_node::{ClipInfo, ClipScrollNode, NodeType};
use clip_scroll_tree::{ClipScrollTree, CoordinateSystemId};
use euclid::{SideOffsets2D, TypedTransform3D, vec2, vec3};
@ -29,7 +29,7 @@ use prim_store::{PrimitiveContainer, PrimitiveIndex};
use prim_store::{PrimitiveStore, RadialGradientPrimitiveCpu};
use prim_store::{RectanglePrimitive, TextRunPrimitiveCpu};
use profiler::{FrameProfileCounters, GpuCacheProfileCounters, TextureCacheProfileCounters};
use render_task::{AlphaRenderItem, ClipChain, RenderTask, RenderTaskId, RenderTaskLocation};
use render_task::{AlphaRenderItem, ClearMode, ClipChain, RenderTask, RenderTaskId, RenderTaskLocation};
use render_task::RenderTaskTree;
use resource_cache::ResourceCache;
use scene::ScenePipeline;
@ -40,6 +40,9 @@ use tiling::{PackedLayer, PackedLayerIndex, PrimitiveFlags, PrimitiveRunCmd, Ren
use tiling::{RenderTargetContext, ScrollbarPrimitive, StackingContext};
use util::{self, pack_as_float, RectHelpers, recycle_vec};
// The blur shader samples BLUR_SAMPLE_SCALE * blur_radius surrounding texels.
const BLUR_SAMPLE_SCALE: f32 = 3.0;
/// Construct a polygon from stacking context boundaries.
/// `anchor` here is an index that's going to be preserved in all the
/// splits of the polygon.
@ -242,7 +245,7 @@ impl FrameBuilder {
clip_sources.push(ClipSource::RoundedRectangle(
region.rect,
region.radii,
ClipMode::Clip,
region.mode,
));
}
@ -557,7 +560,7 @@ impl FrameBuilder {
clip_and_scroll: ClipAndScrollInfo,
info: &LayerPrimitiveInfo,
) {
let prim = PicturePrimitive::new_shadow(shadow, RenderTargetKind::Color);
let prim = PicturePrimitive::new_text_shadow(shadow);
// Create an empty shadow primitive. Insert it into
// the draw lists immediately so that it will be drawn
@ -587,7 +590,7 @@ impl FrameBuilder {
// is then used when blitting the shadow to the final location.
let metadata = &mut self.prim_store.cpu_metadata[prim_index.0];
let prim = &self.prim_store.cpu_pictures[metadata.cpu_prim_index.0];
let shadow = prim.as_shadow();
let shadow = prim.as_text_shadow();
metadata.local_rect = metadata.local_rect.translate(&shadow.offset);
}
@ -676,7 +679,7 @@ impl FrameBuilder {
for (idx, &(shadow_prim_index, _)) in self.shadow_prim_stack.iter().enumerate() {
let shadow_metadata = &self.prim_store.cpu_metadata[shadow_prim_index.0];
let picture = &self.prim_store.cpu_pictures[shadow_metadata.cpu_prim_index.0];
let shadow = picture.as_shadow();
let shadow = picture.as_text_shadow();
if shadow.blur_radius == 0.0 {
fast_shadow_prims.push((idx, shadow.clone()));
}
@ -719,7 +722,7 @@ impl FrameBuilder {
debug_assert_eq!(shadow_metadata.prim_kind, PrimitiveKind::Picture);
let picture =
&mut self.prim_store.cpu_pictures[shadow_metadata.cpu_prim_index.0];
let blur_radius = picture.as_shadow().blur_radius;
let blur_radius = picture.as_text_shadow().blur_radius;
// Only run real blurs here (fast path zero blurs are handled above).
if blur_radius > 0.0 {
@ -1183,7 +1186,7 @@ impl FrameBuilder {
for (idx, &(shadow_prim_index, _)) in self.shadow_prim_stack.iter().enumerate() {
let shadow_metadata = &self.prim_store.cpu_metadata[shadow_prim_index.0];
let picture_prim = &self.prim_store.cpu_pictures[shadow_metadata.cpu_prim_index.0];
let shadow = picture_prim.as_shadow();
let shadow = picture_prim.as_text_shadow();
if shadow.blur_radius == 0.0 {
let mut text_prim = prim.clone();
text_prim.font.color = shadow.color.into();
@ -1238,7 +1241,7 @@ impl FrameBuilder {
&mut self.prim_store.cpu_pictures[shadow_metadata.cpu_prim_index.0];
// Only run real blurs here (fast path zero blurs are handled above).
let blur_radius = picture_prim.as_shadow().blur_radius;
let blur_radius = picture_prim.as_text_shadow().blur_radius;
if blur_radius > 0.0 {
let shadow_rect = rect.inflate(
blur_radius,
@ -1258,7 +1261,7 @@ impl FrameBuilder {
color: &ColorF,
blur_radius: f32,
spread_radius: f32,
border_radius: f32,
border_radius: BorderRadius,
clip_mode: BoxShadowClipMode,
) {
if color.a == 0.0 {
@ -1274,15 +1277,11 @@ impl FrameBuilder {
}
};
// Adjust the shadow box radius as per:
// https://drafts.csswg.org/css-backgrounds-3/#shadow-shape
let sharpness_scale = if border_radius < spread_radius {
let r = border_radius / spread_amount;
1.0 + (r - 1.0) * (r - 1.0) * (r - 1.0)
} else {
1.0
};
let shadow_radius = (border_radius + spread_amount * sharpness_scale).max(0.0);
let shadow_radius = adjust_border_radius_for_box_shadow(
border_radius,
spread_amount,
spread_radius
);
let shadow_rect = prim_info.rect
.translate(box_offset)
.inflate(spread_amount, spread_amount);
@ -1295,7 +1294,7 @@ impl FrameBuilder {
// TODO(gw): Add a fast path for ClipOut + zero border radius!
clips.push(ClipSource::RoundedRectangle(
prim_info.rect,
BorderRadius::uniform(border_radius),
border_radius,
ClipMode::ClipOut
));
@ -1303,14 +1302,18 @@ impl FrameBuilder {
shadow_rect,
LocalClip::RoundedRect(
shadow_rect,
ComplexClipRegion::new(shadow_rect, BorderRadius::uniform(shadow_radius)),
ComplexClipRegion::new(
shadow_rect,
shadow_radius,
ClipMode::Clip,
),
),
)
}
BoxShadowClipMode::Inset => {
clips.push(ClipSource::RoundedRectangle(
shadow_rect,
BorderRadius::uniform(shadow_radius),
shadow_radius,
ClipMode::ClipOut
));
@ -1318,7 +1321,11 @@ impl FrameBuilder {
prim_info.rect,
LocalClip::RoundedRect(
prim_info.rect,
ComplexClipRegion::new(prim_info.rect, BorderRadius::uniform(border_radius)),
ComplexClipRegion::new(
prim_info.rect,
border_radius,
ClipMode::Clip
),
),
)
}
@ -1333,17 +1340,11 @@ impl FrameBuilder {
}),
);
} else {
let shadow = Shadow {
blur_radius,
color: *color,
offset: LayerVector2D::zero(),
};
let blur_offset = 2.0 * blur_radius;
let mut extra_clips = vec![];
let mut pic_prim = PicturePrimitive::new_shadow(shadow, RenderTargetKind::Alpha);
let mut blur_regions = vec![];
let pic_info = match clip_mode {
match clip_mode {
BoxShadowClipMode::Outset => {
let brush_prim = BrushPrimitive {
clip_mode: ClipMode::Clip,
@ -1362,16 +1363,72 @@ impl FrameBuilder {
PrimitiveContainer::Brush(brush_prim),
);
let pic_rect = shadow_rect.inflate(blur_offset, blur_offset);
let blur_range = BLUR_SAMPLE_SCALE * blur_radius;
let size = pic_rect.size;
let tl = LayerSize::new(
blur_radius.max(border_radius.top_left.width),
blur_radius.max(border_radius.top_left.height)
) * BLUR_SAMPLE_SCALE;
let tr = LayerSize::new(
blur_radius.max(border_radius.top_right.width),
blur_radius.max(border_radius.top_right.height)
) * BLUR_SAMPLE_SCALE;
let br = LayerSize::new(
blur_radius.max(border_radius.bottom_right.width),
blur_radius.max(border_radius.bottom_right.height)
) * BLUR_SAMPLE_SCALE;
let bl = LayerSize::new(
blur_radius.max(border_radius.bottom_left.width),
blur_radius.max(border_radius.bottom_left.height)
) * BLUR_SAMPLE_SCALE;
let max_width = tl.width.max(tr.width.max(bl.width.max(br.width)));
let max_height = tl.height.max(tr.height.max(bl.height.max(br.height)));
// Apply a conservative test that if any of the blur regions below
// will overlap, we won't bother applying the region optimization
// and will just blur the entire thing. This should only happen
// in rare cases, where either the blur radius or border radius
// is very large, in which case there's no real point in trying
// to only blur a small region anyway.
if max_width < 0.5 * size.width && max_height < 0.5 * size.height {
blur_regions.push(LayerRect::from_floats(0.0, 0.0, tl.width, tl.height));
blur_regions.push(LayerRect::from_floats(size.width - tr.width, 0.0, size.width, tr.height));
blur_regions.push(LayerRect::from_floats(size.width - br.width, size.height - br.height, size.width, size.height));
blur_regions.push(LayerRect::from_floats(0.0, size.height - bl.height, bl.width, size.height));
blur_regions.push(LayerRect::from_floats(0.0, tl.height, blur_range, size.height - bl.height));
blur_regions.push(LayerRect::from_floats(size.width - blur_range, tr.height, size.width, size.height - br.height));
blur_regions.push(LayerRect::from_floats(tl.width, 0.0, size.width - tr.width, blur_range));
blur_regions.push(LayerRect::from_floats(bl.width, size.height - blur_range, size.width - br.width, size.height));
}
let mut pic_prim = PicturePrimitive::new_box_shadow(
blur_radius,
*color,
blur_regions,
BoxShadowClipMode::Outset,
);
pic_prim.add_primitive(brush_prim_index, clip_and_scroll);
extra_clips.push(ClipSource::RoundedRectangle(
prim_info.rect,
BorderRadius::uniform(border_radius),
border_radius,
ClipMode::ClipOut,
));
let pic_rect = shadow_rect.inflate(blur_offset, blur_offset);
LayerPrimitiveInfo::new(pic_rect)
let pic_info = LayerPrimitiveInfo::new(pic_rect);
self.add_primitive(
clip_and_scroll,
&pic_info,
extra_clips,
PrimitiveContainer::Picture(pic_prim),
);
}
BoxShadowClipMode::Inset => {
let brush_prim = BrushPrimitive {
@ -1392,25 +1449,35 @@ impl FrameBuilder {
PrimitiveContainer::Brush(brush_prim),
);
let pic_rect = prim_info.rect.inflate(blur_offset, blur_offset);
// TODO(gw): Apply minimal blur regions for inset box shadows.
let mut pic_prim = PicturePrimitive::new_box_shadow(
blur_radius,
*color,
blur_regions,
BoxShadowClipMode::Inset,
);
pic_prim.add_primitive(brush_prim_index, clip_and_scroll);
extra_clips.push(ClipSource::RoundedRectangle(
prim_info.rect,
BorderRadius::uniform(border_radius),
border_radius,
ClipMode::Clip,
));
let pic_rect = prim_info.rect.inflate(blur_offset, blur_offset);
LayerPrimitiveInfo::with_clip_rect(pic_rect, prim_info.rect)
}
};
let pic_info = LayerPrimitiveInfo::with_clip_rect(pic_rect, prim_info.rect);
self.add_primitive(
clip_and_scroll,
&pic_info,
extra_clips,
PrimitiveContainer::Picture(pic_prim),
);
self.add_primitive(
clip_and_scroll,
&pic_info,
extra_clips,
PrimitiveContainer::Picture(pic_prim),
);
}
}
}
}
@ -1770,8 +1837,9 @@ impl FrameBuilder {
let transform = scroll_node.world_content_transform;
if !packed_layer.set_transform(transform) {
group.screen_bounding_rect = None;
debug!("\t\tUnable to set transform {:?}", transform);
return;
continue;
}
// Here we move the viewport rectangle into the coordinate system
@ -2045,6 +2113,8 @@ impl FrameBuilder {
current_task_id,
render_tasks,
RenderTargetKind::Color,
&[],
ClearMode::Transparent,
);
let blur_render_task_id = render_tasks.add(blur_render_task);
let item = AlphaRenderItem::HardwareComposite(
@ -2326,3 +2396,67 @@ impl FrameBuilder {
}
}
}
fn adjust_border_radius_for_box_shadow(
radius: BorderRadius,
spread_amount: f32,
spread_radius: f32,
) -> BorderRadius {
BorderRadius {
top_left: adjust_corner_for_box_shadow(
radius.top_left,
spread_radius,
spread_amount,
),
top_right: adjust_corner_for_box_shadow(
radius.top_right,
spread_radius,
spread_amount,
),
bottom_right: adjust_corner_for_box_shadow(
radius.bottom_right,
spread_radius,
spread_amount,
),
bottom_left: adjust_corner_for_box_shadow(
radius.bottom_left,
spread_radius,
spread_amount,
),
}
}
fn adjust_corner_for_box_shadow(
corner: LayoutSize,
spread_amount: f32,
spread_radius: f32,
) -> LayoutSize {
LayoutSize::new(
adjust_radius_for_box_shadow(
corner.width,
spread_radius,
spread_amount
),
adjust_radius_for_box_shadow(
corner.height,
spread_radius,
spread_amount
),
)
}
fn adjust_radius_for_box_shadow(
border_radius: f32,
spread_amount: f32,
spread_radius: f32,
) -> f32 {
// Adjust the shadow box radius as per:
// https://drafts.csswg.org/css-backgrounds-3/#shadow-shape
let sharpness_scale = if border_radius < spread_radius {
let r = border_radius / spread_amount;
1.0 + (r - 1.0) * (r - 1.0) * (r - 1.0)
} else {
1.0
};
(border_radius + spread_amount * sharpness_scale).max(0.0)
}

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

@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::LayerRect;
use gpu_cache::GpuCacheAddress;
use render_task::RenderTaskAddress;
use tiling::PackedLayerIndex;
@ -18,7 +19,7 @@ impl From<PackedLayerIndex> for PackedLayerAddress {
}
#[repr(i32)]
#[derive(Debug)]
#[derive(Debug, Copy, Clone)]
pub enum BlurDirection {
Horizontal = 0,
Vertical,
@ -30,6 +31,7 @@ pub struct BlurInstance {
pub task_address: RenderTaskAddress,
pub src_task_address: RenderTaskAddress,
pub blur_direction: BlurDirection,
pub region: LayerRect,
}
/// A clipping primitive drawn into the clipping mask.

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

@ -2,9 +2,12 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::{ClipAndScrollInfo, Shadow};
use prim_store::PrimitiveIndex;
use render_task::RenderTaskId;
use api::{ColorF, ClipAndScrollInfo, device_length, DeviceIntSize};
use api::{BoxShadowClipMode, LayerRect, Shadow};
use frame_builder::PrimitiveContext;
use gpu_cache::GpuDataRequest;
use prim_store::{PrimitiveIndex, PrimitiveMetadata};
use render_task::{ClearMode, RenderTask, RenderTaskId, RenderTaskTree};
use tiling::RenderTargetKind;
/*
@ -25,19 +28,23 @@ pub struct PrimitiveRun {
}
#[derive(Debug)]
pub enum CompositeOp {
Shadow(Shadow),
// TODO(gw): Support other composite ops, such
// as blur, blend etc.
pub enum PictureKind {
TextShadow {
shadow: Shadow,
},
BoxShadow {
blur_radius: f32,
color: ColorF,
blur_regions: Vec<LayerRect>,
clip_mode: BoxShadowClipMode,
},
}
#[derive(Debug)]
pub struct PicturePrimitive {
pub prim_runs: Vec<PrimitiveRun>,
pub composite_op: CompositeOp,
pub render_task_id: Option<RenderTaskId>,
pub kind: RenderTargetKind,
pub kind: PictureKind,
// TODO(gw): Add a mode that specifies if this
// picture should be rasterized in
@ -45,21 +52,38 @@ pub struct PicturePrimitive {
}
impl PicturePrimitive {
pub fn new_shadow(
shadow: Shadow,
kind: RenderTargetKind,
) -> PicturePrimitive {
pub fn new_text_shadow(shadow: Shadow) -> PicturePrimitive {
PicturePrimitive {
prim_runs: Vec::new(),
composite_op: CompositeOp::Shadow(shadow),
render_task_id: None,
kind,
kind: PictureKind::TextShadow {
shadow,
},
}
}
pub fn as_shadow(&self) -> &Shadow {
match self.composite_op {
CompositeOp::Shadow(ref shadow) => shadow,
pub fn new_box_shadow(
blur_radius: f32,
color: ColorF,
blur_regions: Vec<LayerRect>,
clip_mode: BoxShadowClipMode,
) -> PicturePrimitive {
PicturePrimitive {
prim_runs: Vec::new(),
render_task_id: None,
kind: PictureKind::BoxShadow {
blur_radius,
color,
blur_regions,
clip_mode,
},
}
}
pub fn as_text_shadow(&self) -> &Shadow {
match self.kind {
PictureKind::TextShadow { ref shadow } => shadow,
PictureKind::BoxShadow { .. } => panic!("bug: not a text shadow")
}
}
@ -82,4 +106,83 @@ impl PicturePrimitive {
clip_and_scroll,
});
}
pub fn prepare_for_render(
&mut self,
prim_index: PrimitiveIndex,
prim_metadata: &PrimitiveMetadata,
prim_context: &PrimitiveContext,
render_tasks: &mut RenderTaskTree,
) {
// This is a shadow element. Create a render task that will
// render the text run to a target, and then apply a gaussian
// blur to that text run in order to build the actual primitive
// which will be blitted to the framebuffer.
let cache_width =
(prim_metadata.local_rect.size.width * prim_context.device_pixel_ratio).ceil() as i32;
let cache_height =
(prim_metadata.local_rect.size.height * prim_context.device_pixel_ratio).ceil() as i32;
let cache_size = DeviceIntSize::new(cache_width, cache_height);
let (blur_radius, target_kind, blur_regions, clear_mode) = match self.kind {
PictureKind::TextShadow { ref shadow } => {
let dummy: &[LayerRect] = &[];
(shadow.blur_radius, RenderTargetKind::Color, dummy, ClearMode::Transparent)
}
PictureKind::BoxShadow { blur_radius, clip_mode, ref blur_regions, .. } => {
let clear_mode = match clip_mode {
BoxShadowClipMode::Outset => ClearMode::One,
BoxShadowClipMode::Inset => ClearMode::Zero,
};
(blur_radius, RenderTargetKind::Alpha, blur_regions.as_slice(), clear_mode)
}
};
let blur_radius = device_length(blur_radius, prim_context.device_pixel_ratio);
let picture_task = RenderTask::new_picture(
cache_size,
prim_index,
target_kind,
);
let picture_task_id = render_tasks.add(picture_task);
let render_task = RenderTask::new_blur(
blur_radius,
picture_task_id,
render_tasks,
target_kind,
blur_regions,
clear_mode,
);
self.render_task_id = Some(render_tasks.add(render_task));
}
pub fn write_gpu_blocks(&self, mut request: GpuDataRequest) {
match self.kind {
PictureKind::TextShadow { ref shadow } => {
request.push(shadow.color);
request.push([
shadow.offset.x,
shadow.offset.y,
shadow.blur_radius,
0.0,
]);
}
PictureKind::BoxShadow { blur_radius, color, .. } => {
request.push(color);
request.push([
0.0,
0.0,
blur_radius,
0.0,
]);
}
}
}
pub fn target_kind(&self) -> RenderTargetKind {
match self.kind {
PictureKind::TextShadow { .. } => RenderTargetKind::Color,
PictureKind::BoxShadow { .. } => RenderTargetKind::Alpha,
}
}
}

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

@ -2,13 +2,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::{BorderRadius, BuiltDisplayList, ColorF, ComplexClipRegion, DeviceIntRect, DeviceIntSize};
use api::{BorderRadius, BuiltDisplayList, ColorF, ComplexClipRegion, DeviceIntRect};
use api::{DevicePoint, ExtendMode, FontInstance, FontRenderMode, GlyphInstance, GlyphKey};
use api::{GradientStop, ImageKey, ImageRendering, ItemRange, ItemTag, LayerPoint, LayerRect};
use api::{LayerSize, LayerVector2D, LineOrientation, LineStyle};
use api::{TileOffset, YuvColorSpace, YuvFormat, device_length};
use api::{ClipMode, LayerSize, LayerVector2D, LineOrientation, LineStyle};
use api::{TileOffset, YuvColorSpace, YuvFormat};
use border::BorderCornerInstance;
use clip::{ClipMode, ClipSourcesHandle, ClipStore, Geometry};
use clip::{ClipSourcesHandle, ClipStore, Geometry};
use frame_builder::PrimitiveContext;
use gpu_cache::{GpuBlockData, GpuCache, GpuCacheAddress, GpuCacheHandle, GpuDataRequest,
ToGpuBlocks};
@ -167,17 +167,29 @@ impl ToGpuBlocks for RectanglePrimitive {
#[derive(Debug)]
pub struct BrushPrimitive {
pub clip_mode: ClipMode,
pub radius: f32,
pub radius: BorderRadius,
}
impl ToGpuBlocks for BrushPrimitive {
fn write_gpu_blocks(&self, mut request: GpuDataRequest) {
request.push([
self.clip_mode as u32 as f32,
self.radius,
0.0,
0.0,
0.0
]);
request.push([
self.radius.top_left.width,
self.radius.top_left.height,
self.radius.top_right.width,
self.radius.top_right.height,
]);
request.push([
self.radius.bottom_right.width,
self.radius.bottom_right.height,
self.radius.bottom_left.width,
self.radius.bottom_left.height,
]);
}
}
@ -1037,46 +1049,20 @@ impl PrimitiveStore {
prim_context: &PrimitiveContext,
resource_cache: &mut ResourceCache,
gpu_cache: &mut GpuCache,
// For some primitives, we need to mark dependencies as needed for rendering
// without spawning new tasks, since there will be another call to
// `prepare_prim_for_render_inner` specifically for this primitive later on.
render_tasks: Option<&mut RenderTaskTree>,
render_tasks: &mut RenderTaskTree,
text_run_mode: TextRunMode,
) {
let metadata = &mut self.cpu_metadata[prim_index.0];
match metadata.prim_kind {
PrimitiveKind::Rectangle | PrimitiveKind::Border | PrimitiveKind::Line => {}
PrimitiveKind::Picture => {
let picture = &mut self.cpu_pictures[metadata.cpu_prim_index.0];
// This is a shadow element. Create a render task that will
// render the text run to a target, and then apply a gaussian
// blur to that text run in order to build the actual primitive
// which will be blitted to the framebuffer.
let cache_width =
(metadata.local_rect.size.width * prim_context.device_pixel_ratio).ceil() as i32;
let cache_height =
(metadata.local_rect.size.height * prim_context.device_pixel_ratio).ceil() as i32;
let cache_size = DeviceIntSize::new(cache_width, cache_height);
let blur_radius = picture.as_shadow().blur_radius;
let blur_radius = device_length(blur_radius, prim_context.device_pixel_ratio);
// ignore new tasks if we are in a dependency context
picture.render_task_id = render_tasks.map(|rt| {
let picture_task = RenderTask::new_picture(
cache_size,
self.cpu_pictures[metadata.cpu_prim_index.0]
.prepare_for_render(
prim_index,
picture.kind,
metadata,
prim_context,
render_tasks
);
let picture_task_id = rt.add(picture_task);
let render_task = RenderTask::new_blur(
blur_radius,
picture_task_id,
rt,
picture.kind
);
rt.add(render_task)
});
}
PrimitiveKind::TextRun => {
let text = &mut self.cpu_text_runs[metadata.cpu_prim_index.0];
@ -1173,15 +1159,8 @@ impl PrimitiveStore {
text.write_gpu_blocks(&mut request);
}
PrimitiveKind::Picture => {
let picture = &self.cpu_pictures[metadata.cpu_prim_index.0];
let shadow = picture.as_shadow();
request.push(shadow.color);
request.push([
shadow.offset.x,
shadow.offset.y,
shadow.blur_radius,
0.0,
]);
self.cpu_pictures[metadata.cpu_prim_index.0]
.write_gpu_blocks(request);
}
PrimitiveKind::Brush => {
let brush = &self.cpu_brushes[metadata.cpu_prim_index.0];
@ -1342,7 +1321,7 @@ impl PrimitiveStore {
prim_context,
resource_cache,
gpu_cache,
None,
render_tasks,
TextRunMode::Shadow,
);
}
@ -1365,7 +1344,7 @@ impl PrimitiveStore {
prim_context,
resource_cache,
gpu_cache,
Some(render_tasks),
render_tasks,
TextRunMode::Normal,
);

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

@ -22,7 +22,8 @@ use resource_cache::ResourceCache;
use scene::Scene;
#[cfg(feature = "debugger")]
use serde_json;
use std::sync::{Arc, Mutex};
use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering};
use std::sync::Arc;
use std::sync::mpsc::Sender;
use std::u32;
use texture_cache::TextureCache;
@ -124,6 +125,9 @@ enum DocumentOp {
Rendered(RendererFrame),
}
/// The unique id for WR resource identification.
static NEXT_NAMESPACE_ID: AtomicUsize = ATOMIC_USIZE_INIT;
/// The render backend is responsible for transforming high level display lists into
/// GPU-friendly work which is then submitted to the renderer in the form of a frame::Frame.
///
@ -133,7 +137,6 @@ pub struct RenderBackend {
payload_rx: PayloadReceiver,
payload_tx: PayloadSender,
result_tx: Sender<ResultMsg>,
next_namespace_id: IdNamespace,
default_device_pixel_ratio: f32,
gpu_cache: GpuCache,
@ -142,7 +145,7 @@ pub struct RenderBackend {
frame_config: FrameBuilderConfig,
documents: FastHashMap<DocumentId, Document>,
notifier: Arc<Mutex<Option<Box<RenderNotifier>>>>,
notifier: Box<RenderNotifier>,
recorder: Option<Box<ApiRecordingReceiver>>,
enable_render_on_scroll: bool,
@ -157,12 +160,15 @@ impl RenderBackend {
default_device_pixel_ratio: f32,
texture_cache: TextureCache,
workers: Arc<ThreadPool>,
notifier: Arc<Mutex<Option<Box<RenderNotifier>>>>,
notifier: Box<RenderNotifier>,
frame_config: FrameBuilderConfig,
recorder: Option<Box<ApiRecordingReceiver>>,
blob_image_renderer: Option<Box<BlobImageRenderer>>,
enable_render_on_scroll: bool,
) -> RenderBackend {
// The namespace_id should start from 1.
NEXT_NAMESPACE_ID.fetch_add(1, Ordering::Relaxed);
let resource_cache = ResourceCache::new(texture_cache, workers, blob_image_renderer);
register_thread_with_profiler("Backend".to_string());
@ -177,7 +183,6 @@ impl RenderBackend {
gpu_cache: GpuCache::new(),
frame_config,
documents: FastHashMap::default(),
next_namespace_id: IdNamespace(1),
notifier,
recorder,
@ -421,6 +426,10 @@ impl RenderBackend {
}
}
fn next_namespace_id(&self) -> IdNamespace {
IdNamespace(NEXT_NAMESPACE_ID.fetch_add(1, Ordering::Relaxed) as u32)
}
pub fn run(&mut self, mut profile_counters: BackendProfileCounters) {
let mut frame_counter: u32 = 0;
@ -435,8 +444,7 @@ impl RenderBackend {
msg
}
Err(..) => {
let notifier = self.notifier.lock();
notifier.unwrap().as_mut().unwrap().shut_down();
self.notifier.shut_down();
break;
}
};
@ -463,9 +471,7 @@ impl RenderBackend {
tx.send(glyph_indices).unwrap();
}
ApiMsg::CloneApi(sender) => {
let namespace = self.next_namespace_id;
self.next_namespace_id = IdNamespace(namespace.0 + 1);
sender.send(namespace).unwrap();
sender.send(self.next_namespace_id()).unwrap();
}
ApiMsg::AddDocument(document_id, initial_size) => {
let document = Document::new(
@ -504,8 +510,7 @@ impl RenderBackend {
self.documents.remove(&document_id);
}
ApiMsg::ExternalEvent(evt) => {
let notifier = self.notifier.lock();
notifier.unwrap().as_mut().unwrap().external_event(evt);
self.notifier.external_event(evt);
}
ApiMsg::ClearNamespace(namespace_id) => {
self.resource_cache.clear_namespace(namespace_id);
@ -530,12 +535,7 @@ impl RenderBackend {
// We use new_frame_ready to wake up the renderer and get the
// resource updates processed, but the UpdateResources message
// will cancel rendering the frame.
self.notifier
.lock()
.unwrap()
.as_mut()
.unwrap()
.new_frame_ready();
self.notifier.new_frame_ready();
}
ApiMsg::DebugCommand(option) => {
let msg = match option {
@ -550,12 +550,10 @@ impl RenderBackend {
_ => ResultMsg::DebugCommand(option),
};
self.result_tx.send(msg).unwrap();
let notifier = self.notifier.lock();
notifier.unwrap().as_mut().unwrap().new_frame_ready();
self.notifier.new_frame_ready();
}
ApiMsg::ShutDown => {
let notifier = self.notifier.lock();
notifier.unwrap().as_mut().unwrap().shut_down();
self.notifier.shut_down();
break;
}
}
@ -582,31 +580,11 @@ impl RenderBackend {
) {
self.publish_frame(document_id, frame, profile_counters);
// TODO(gw): This is kindof bogus to have to lock the notifier
// each time it's used. This is due to some nastiness
// in initialization order for Servo. Perhaps find a
// cleaner way to do this, or use the OnceMutex on crates.io?
let mut notifier = self.notifier.lock();
notifier
.as_mut()
.unwrap()
.as_mut()
.unwrap()
.new_frame_ready();
self.notifier.new_frame_ready();
}
fn notify_compositor_of_new_scroll_frame(&mut self, composite_needed: bool) {
// TODO(gw): This is kindof bogus to have to lock the notifier
// each time it's used. This is due to some nastiness
// in initialization order for Servo. Perhaps find a
// cleaner way to do this, or use the OnceMutex on crates.io?
let mut notifier = self.notifier.lock();
notifier
.as_mut()
.unwrap()
.as_mut()
.unwrap()
.new_scroll_frame_ready(composite_needed);
fn notify_compositor_of_new_scroll_frame(&self, composite_needed: bool) {
self.notifier.new_scroll_frame_ready(composite_needed);
}

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

@ -4,7 +4,7 @@
use api::{ClipId, DeviceIntLength, DeviceIntPoint, DeviceIntRect, DeviceIntSize};
use api::{FilterOp, MixBlendMode};
use api::PipelineId;
use api::{LayerRect, PipelineId};
use clip::{ClipSource, ClipSourcesWeakHandle, ClipStore};
use clip_scroll_tree::CoordinateSystemId;
use gpu_cache::GpuCacheHandle;
@ -264,6 +264,7 @@ pub struct PictureTask {
pub struct BlurTask {
pub blur_radius: DeviceIntLength,
pub target_kind: RenderTargetKind,
pub regions: Vec<LayerRect>,
}
#[derive(Debug)]
@ -282,12 +283,23 @@ pub enum RenderTaskKind {
Alias(RenderTaskId),
}
#[derive(Debug, Copy, Clone)]
pub enum ClearMode {
// Applicable to color and alpha targets.
Zero,
One,
// Applicable to color targets only.
Transparent,
}
#[derive(Debug)]
pub struct RenderTask {
pub cache_key: Option<RenderTaskKey>,
pub location: RenderTaskLocation,
pub children: Vec<RenderTaskId>,
pub kind: RenderTaskKind,
pub clear_mode: ClearMode,
}
impl RenderTask {
@ -305,6 +317,7 @@ impl RenderTask {
items: Vec::new(),
frame_output_pipeline_id,
}),
clear_mode: ClearMode::Transparent,
}
}
@ -321,6 +334,11 @@ impl RenderTask {
prim_index: PrimitiveIndex,
target_kind: RenderTargetKind,
) -> RenderTask {
let clear_mode = match target_kind {
RenderTargetKind::Color => ClearMode::Transparent,
RenderTargetKind::Alpha => ClearMode::One,
};
RenderTask {
cache_key: None,
children: Vec::new(),
@ -329,6 +347,7 @@ impl RenderTask {
prim_index,
target_kind,
}),
clear_mode,
}
}
@ -338,6 +357,7 @@ impl RenderTask {
children: Vec::new(),
location: RenderTaskLocation::Dynamic(None, screen_rect.size),
kind: RenderTaskKind::Readback(screen_rect),
clear_mode: ClearMode::Transparent,
}
}
@ -420,6 +440,7 @@ impl RenderTask {
geometry_kind,
coordinate_system_id: prim_coordinate_system_id,
}),
clear_mode: ClearMode::One,
})
}
@ -443,6 +464,8 @@ impl RenderTask {
src_task_id: RenderTaskId,
render_tasks: &mut RenderTaskTree,
target_kind: RenderTargetKind,
regions: &[LayerRect],
clear_mode: ClearMode,
) -> RenderTask {
let blur_target_size = render_tasks.get(src_task_id).get_dynamic_size();
@ -453,7 +476,9 @@ impl RenderTask {
kind: RenderTaskKind::VerticalBlur(BlurTask {
blur_radius,
target_kind,
regions: regions.to_vec(),
}),
clear_mode,
};
let blur_task_v_id = render_tasks.add(blur_task_v);
@ -465,7 +490,9 @@ impl RenderTask {
kind: RenderTaskKind::HorizontalBlur(BlurTask {
blur_radius,
target_kind,
regions: regions.to_vec(),
}),
clear_mode,
};
blur_task_h

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

@ -55,7 +55,7 @@ use std::f32;
use std::mem;
use std::path::PathBuf;
use std::rc::Rc;
use std::sync::{Arc, Mutex};
use std::sync::Arc;
use std::sync::mpsc::{channel, Receiver, Sender};
use std::thread;
use texture_cache::TextureCache;
@ -325,6 +325,11 @@ const DESC_BLUR: VertexDescriptor = VertexDescriptor {
count: 1,
kind: VertexAttributeKind::I32,
},
VertexAttribute {
name: "aBlurRegion",
count: 4,
kind: VertexAttributeKind::F32
},
],
};
@ -925,20 +930,14 @@ struct PrimitiveShader {
}
struct FileWatcher {
notifier: Arc<Mutex<Option<Box<RenderNotifier>>>>,
notifier: Box<RenderNotifier>,
result_tx: Sender<ResultMsg>,
}
impl FileWatcherHandler for FileWatcher {
fn file_changed(&self, path: PathBuf) {
self.result_tx.send(ResultMsg::RefreshShader(path)).ok();
let mut notifier = self.notifier.lock();
notifier
.as_mut()
.unwrap()
.as_mut()
.unwrap()
.new_frame_ready();
self.notifier.new_frame_ready();
}
}
@ -1132,8 +1131,6 @@ pub struct Renderer {
ps_split_composite: LazilyCompiledShader,
ps_composite: LazilyCompiledShader,
notifier: Arc<Mutex<Option<Box<RenderNotifier>>>>,
max_texture_size: u32,
max_recorded_profiles: usize,
@ -1229,6 +1226,7 @@ impl Renderer {
/// [rendereroptions]: struct.RendererOptions.html
pub fn new(
gl: Rc<gl::Gl>,
notifier: Box<RenderNotifier>,
mut options: RendererOptions,
) -> Result<(Renderer, RenderApiSender), RendererError> {
let (api_tx, api_rx) = try!{ channel::msg_channel() };
@ -1236,12 +1234,11 @@ impl Renderer {
let (result_tx, result_rx) = channel();
let gl_type = gl.get_type();
let notifier = Arc::new(Mutex::new(None));
let debug_server = DebugServer::new(api_tx.clone());
let file_watch_handler = FileWatcher {
result_tx: result_tx.clone(),
notifier: Arc::clone(&notifier),
notifier: notifier.clone(),
};
let mut device = Device::new(
@ -1652,7 +1649,7 @@ impl Renderer {
device.end_frame();
let backend_notifier = Arc::clone(&notifier);
let backend_notifier = notifier.clone();
let default_font_render_mode = match (options.enable_aa, options.enable_subpixel_aa) {
(true, true) => FontRenderMode::Subpixel,
@ -1735,7 +1732,6 @@ impl Renderer {
ps_split_composite,
ps_composite,
ps_line,
notifier,
debug: debug_renderer,
debug_flags,
enable_batcher: options.enable_batcher,
@ -1794,15 +1790,6 @@ impl Renderer {
(color_space as usize)
}
/// Sets the new RenderNotifier.
///
/// The RenderNotifier will be called when processing e.g. of a (scrolling) frame is done,
/// and therefore the screen should be updated.
pub fn set_render_notifier(&self, notifier: Box<RenderNotifier>) {
let mut notifier_arc = self.notifier.lock().unwrap();
*notifier_arc = Some(notifier);
}
/// Returns the Epoch of the current frame in a pipeline.
pub fn current_epoch(&self, pipeline_id: PipelineId) -> Option<Epoch> {
self.pipeline_epoch_map.get(&pipeline_id).cloned()
@ -2890,6 +2877,7 @@ impl Renderer {
target: &AlphaRenderTarget,
target_size: DeviceUintSize,
projection: &Transform3D<f32>,
render_tasks: &RenderTaskTree,
) {
self.gpu_profile.add_sampler(GPU_SAMPLER_TAG_ALPHA);
@ -2908,6 +2896,14 @@ impl Renderer {
let clear_color = [1.0, 1.0, 1.0, 0.0];
self.device
.clear_target_rect(Some(clear_color), None, target.used_rect());
let zero_color = [0.0, 0.0, 0.0, 0.0];
for task_id in &target.zero_clears {
let task = render_tasks.get(*task_id);
let (rect, _) = task.get_target_rect();
self.device
.clear_target_rect(Some(zero_color), None, rect);
}
}
// Draw any blurs for this target.
@ -3238,6 +3234,7 @@ impl Renderer {
target,
pass.max_alpha_target_size,
&projection,
&frame.render_tasks,
);
}

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

@ -430,7 +430,7 @@ impl ResourceCache {
self.blob_image_renderer
.as_mut()
.unwrap()
.update(image_key, mem::replace(blob, BlobImageData::new()));
.update(image_key, mem::replace(blob, BlobImageData::new()), dirty_rect);
}
ImageResource {

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

@ -21,7 +21,7 @@ use prim_store::{DeferredResolve, TextRunMode};
use profiler::FrameProfileCounters;
use render_task::{AlphaRenderItem, ClipWorkItem, MaskGeometryKind, MaskSegment};
use render_task::{RenderTaskAddress, RenderTaskId, RenderTaskKey, RenderTaskKind};
use render_task::{RenderTaskLocation, RenderTaskTree};
use render_task::{BlurTask, ClearMode, RenderTaskLocation, RenderTaskTree};
use renderer::BlendMode;
use renderer::ImageBufferKind;
use resource_cache::{GlyphFetchResult, ResourceCache};
@ -427,6 +427,7 @@ impl AlphaRenderItem {
{
let sub_index = i as i32;
match *instance_kind {
BorderCornerInstance::None => {}
BorderCornerInstance::Single => {
batch.push(base_instance.build(
sub_index,
@ -580,7 +581,7 @@ impl AlphaRenderItem {
let textures = BatchTextures::render_target_cache();
let kind = BatchKind::Transformable(
transform_kind,
TransformBatchKind::CacheImage(picture.kind),
TransformBatchKind::CacheImage(picture.target_kind()),
);
let key = BatchKey::new(kind, blend_mode, textures);
let batch = batch_list.get_suitable_batch(key, item_bounding_rect);
@ -1137,23 +1138,23 @@ impl RenderTarget for ColorRenderTarget {
});
}
}
RenderTaskKind::VerticalBlur(..) => {
// Find the child render task that we are applying
// a vertical blur on.
self.vertical_blurs.push(BlurInstance {
task_address: render_tasks.get_task_address(task_id),
src_task_address: render_tasks.get_task_address(task.children[0]),
blur_direction: BlurDirection::Vertical,
});
RenderTaskKind::VerticalBlur(ref info) => {
info.add_instances(
&mut self.vertical_blurs,
task_id,
task.children[0],
BlurDirection::Vertical,
render_tasks,
);
}
RenderTaskKind::HorizontalBlur(..) => {
// Find the child render task that we are applying
// a horizontal blur on.
self.horizontal_blurs.push(BlurInstance {
task_address: render_tasks.get_task_address(task_id),
src_task_address: render_tasks.get_task_address(task.children[0]),
blur_direction: BlurDirection::Horizontal,
});
RenderTaskKind::HorizontalBlur(ref info) => {
info.add_instances(
&mut self.horizontal_blurs,
task_id,
task.children[0],
BlurDirection::Horizontal,
render_tasks,
);
}
RenderTaskKind::Picture(ref task_info) => {
let prim_metadata = ctx.prim_store.get_metadata(task_info.prim_index);
@ -1244,6 +1245,7 @@ pub struct AlphaRenderTarget {
// List of blur operations to apply for this render target.
pub vertical_blurs: Vec<BlurInstance>,
pub horizontal_blurs: Vec<BlurInstance>,
pub zero_clears: Vec<RenderTaskId>,
allocator: TextureAllocator,
}
@ -1258,6 +1260,7 @@ impl RenderTarget for AlphaRenderTarget {
rect_cache_prims: Vec::new(),
vertical_blurs: Vec::new(),
horizontal_blurs: Vec::new(),
zero_clears: Vec::new(),
allocator: TextureAllocator::new(size.expect("bug: alpha targets need size")),
}
}
@ -1275,6 +1278,17 @@ impl RenderTarget for AlphaRenderTarget {
clip_store: &ClipStore,
) {
let task = render_tasks.get(task_id);
match task.clear_mode {
ClearMode::Zero => {
self.zero_clears.push(task_id);
}
ClearMode::One => {}
ClearMode::Transparent => {
panic!("bug: invalid clear mode for alpha task");
}
}
match task.kind {
RenderTaskKind::Alias(..) => {
panic!("BUG: add_task() called on invalidated task");
@ -1283,23 +1297,23 @@ impl RenderTarget for AlphaRenderTarget {
RenderTaskKind::Readback(..) => {
panic!("Should not be added to alpha target!");
}
RenderTaskKind::VerticalBlur(..) => {
// Find the child render task that we are applying
// a vertical blur on.
self.vertical_blurs.push(BlurInstance {
task_address: render_tasks.get_task_address(task_id),
src_task_address: render_tasks.get_task_address(task.children[0]),
blur_direction: BlurDirection::Vertical,
});
RenderTaskKind::VerticalBlur(ref info) => {
info.add_instances(
&mut self.vertical_blurs,
task_id,
task.children[0],
BlurDirection::Vertical,
render_tasks,
);
}
RenderTaskKind::HorizontalBlur(..) => {
// Find the child render task that we are applying
// a horizontal blur on.
self.horizontal_blurs.push(BlurInstance {
task_address: render_tasks.get_task_address(task_id),
src_task_address: render_tasks.get_task_address(task.children[0]),
blur_direction: BlurDirection::Horizontal,
});
RenderTaskKind::HorizontalBlur(ref info) => {
info.add_instances(
&mut self.horizontal_blurs,
task_id,
task.children[0],
BlurDirection::Horizontal,
render_tasks,
);
}
RenderTaskKind::Picture(ref task_info) => {
let prim_metadata = ctx.prim_store.get_metadata(task_info.prim_index);
@ -1873,3 +1887,32 @@ fn resolve_image(
None => (SourceTexture::Invalid, GpuCacheHandle::new()),
}
}
impl BlurTask {
fn add_instances(
&self,
instances: &mut Vec<BlurInstance>,
task_id: RenderTaskId,
source_task_id: RenderTaskId,
blur_direction: BlurDirection,
render_tasks: &RenderTaskTree,
) {
let instance = BlurInstance {
task_address: render_tasks.get_task_address(task_id),
src_task_address: render_tasks.get_task_address(source_task_id),
blur_direction,
region: LayerRect::zero(),
};
if self.regions.is_empty() {
instances.push(instance);
} else {
for region in &self.regions {
instances.push(BlurInstance {
region: *region,
..instance
});
}
}
}
}

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

@ -1,6 +1,6 @@
[package]
name = "webrender_api"
version = "0.52.1"
version = "0.53.0"
authors = ["Glenn Watson <gw@intuitionlibrary.com>"]
license = "MPL-2.0"
repository = "https://github.com/servo/webrender"
@ -15,7 +15,6 @@ bitflags = "1.0"
bincode = "0.9"
byteorder = "1.0"
euclid = "0.15"
heapsize = ">= 0.3.6, < 0.5"
ipc-channel = {version = "0.9", optional = true}
serde = { version = "1.0", features = ["rc", "derive"] }
time = "0.1"

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

@ -873,10 +873,11 @@ pub struct DynamicProperties {
}
pub trait RenderNotifier: Send {
fn new_frame_ready(&mut self);
fn new_scroll_frame_ready(&mut self, composite_needed: bool);
fn external_event(&mut self, _evt: ExternalEvent) {
fn clone(&self) -> Box<RenderNotifier>;
fn new_frame_ready(&self);
fn new_scroll_frame_ready(&self, composite_needed: bool);
fn external_event(&self, _evt: ExternalEvent) {
unimplemented!()
}
fn shut_down(&mut self) {}
fn shut_down(&self) {}
}

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

@ -16,7 +16,6 @@ pub struct ColorF {
pub b: f32,
pub a: f32,
}
known_heap_size!(0, ColorF);
impl ColorF {
/// Constructs a new `ColorF` from its components.

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

@ -6,6 +6,7 @@ use {ColorF, FontInstanceKey, ImageKey, LayerPixel, LayoutPixel, LayoutPoint, La
LayoutSize, LayoutTransform};
use {GlyphOptions, LayoutVector2D, PipelineId, PropertyBinding};
use euclid::{SideOffsets2D, TypedRect, TypedSideOffsets2D};
use std::ops::Not;
// NOTE: some of these structs have an "IMPLICIT" comment.
// This indicates that the BuiltDisplayList will have serialized
@ -297,7 +298,7 @@ pub struct BoxShadowDisplayItem {
pub color: ColorF,
pub blur_radius: f32,
pub spread_radius: f32,
pub border_radius: f32,
pub border_radius: BorderRadius,
pub clip_mode: BoxShadowClipMode,
}
@ -336,7 +337,6 @@ pub struct GradientStop {
pub offset: f32,
pub color: ColorF,
}
known_heap_size!(0, GradientStop);
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct RadialGradient {
@ -376,8 +376,6 @@ pub enum ScrollPolicy {
Fixed = 1,
}
known_heap_size!(0, ScrollPolicy);
#[repr(u32)]
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub enum TransformStyle {
@ -547,12 +545,31 @@ impl LocalClip {
ComplexClipRegion {
rect: complex.rect.translate(offset),
radii: complex.radii,
mode: complex.mode,
},
),
}
}
}
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum ClipMode {
Clip, // Pixels inside the region are visible.
ClipOut, // Pixels outside the region are visible.
}
impl Not for ClipMode {
type Output = ClipMode;
fn not(self) -> ClipMode {
match self {
ClipMode::Clip => ClipMode::ClipOut,
ClipMode::ClipOut => ClipMode::Clip,
}
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct ComplexClipRegion {
@ -560,6 +577,9 @@ pub struct ComplexClipRegion {
pub rect: LayoutRect,
/// Border radii of this rectangle.
pub radii: BorderRadius,
/// Whether we are clipping inside or outside
/// the region.
pub mode: ClipMode,
}
impl BorderRadius {
@ -619,8 +639,12 @@ impl BorderRadius {
impl ComplexClipRegion {
/// Create a new complex clip region.
pub fn new(rect: LayoutRect, radii: BorderRadius) -> ComplexClipRegion {
ComplexClipRegion { rect, radii }
pub fn new(
rect: LayoutRect,
radii: BorderRadius,
mode: ClipMode,
) -> ComplexClipRegion {
ComplexClipRegion { rect, radii, mode }
}
}
@ -672,21 +696,3 @@ impl ClipId {
}
}
}
macro_rules! define_empty_heap_size_of {
($name:ident) => {
impl ::heapsize::HeapSizeOf for $name {
fn heap_size_of_children(&self) -> usize { 0 }
}
}
}
define_empty_heap_size_of!(ClipAndScrollInfo);
define_empty_heap_size_of!(ClipId);
define_empty_heap_size_of!(ImageKey);
define_empty_heap_size_of!(LocalClip);
define_empty_heap_size_of!(MixBlendMode);
define_empty_heap_size_of!(RepeatMode);
define_empty_heap_size_of!(ScrollSensitivity);
define_empty_heap_size_of!(StickySideConstraint);
define_empty_heap_size_of!(TransformStyle);

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

@ -12,7 +12,7 @@ use {LineDisplayItem, LineOrientation, LineStyle, LocalClip, MixBlendMode, Pipel
use {PropertyBinding, PushStackingContextDisplayItem, RadialGradient, RadialGradientDisplayItem};
use {RectangleDisplayItem, ScrollFrameDisplayItem, ScrollPolicy, ScrollSensitivity};
use {SpecificDisplayItem, StackingContext, StickyFrameDisplayItem, StickyFrameInfo};
use {TextDisplayItem, Shadow, TransformStyle, YuvColorSpace, YuvData};
use {BorderRadius, TextDisplayItem, Shadow, TransformStyle, YuvColorSpace, YuvData};
use YuvImageDisplayItem;
use bincode;
use serde::{Deserialize, Serialize, Serializer};
@ -153,23 +153,25 @@ fn skip_slice<T: for<'de> Deserialize<'de>>(
data: &mut &[u8],
) -> (ItemRange<T>, usize) {
let base = list.data.as_ptr() as usize;
let start = data.as_ptr() as usize;
// Read through the values (this is a bit of a hack to reuse logic)
let mut iter = AuxIter::<T>::new(*data);
let count = iter.len();
for _ in &mut iter {}
let end = iter.data.as_ptr() as usize;
let byte_size: usize = bincode::deserialize_from(data, bincode::Infinite)
.expect("MEH: malicious input?");
let start = data.as_ptr() as usize;
let item_count: usize = bincode::deserialize_from(data, bincode::Infinite)
.expect("MEH: malicious input?");
// Remember how many bytes item_count occupied
let item_count_size = data.as_ptr() as usize - start;
let range = ItemRange {
start: start - base,
length: end - start,
start: start - base, // byte offset to item_count
length: byte_size + item_count_size, // number of bytes for item_count + payload
_boo: PhantomData,
};
// Adjust data pointer to skip read values
*data = &data[range.length ..];
(range, count)
*data = &data[byte_size ..];
(range, item_count)
}
@ -737,12 +739,29 @@ impl DisplayListBuilder {
let len = iter.len();
let mut count = 0;
// Format:
// payload_byte_size: usize, item_count: usize, [I; item_count]
// We write a dummy value so there's room for later
let byte_size_offset = self.data.len();
serialize_fast(&mut self.data, &0usize);
serialize_fast(&mut self.data, &len);
let payload_offset = self.data.len();
for elem in iter {
count += 1;
serialize_fast(&mut self.data, &elem);
}
// Now write the actual byte_size
let final_offset = self.data.len();
let byte_size = final_offset - payload_offset;
// Note we don't use serialize_fast because we don't want to change the Vec's len
bincode::serialize_into(&mut &mut self.data[byte_size_offset..],
&byte_size,
bincode::Infinite).unwrap();
debug_assert_eq!(len, count);
}
@ -1024,7 +1043,7 @@ impl DisplayListBuilder {
color: ColorF,
blur_radius: f32,
spread_radius: f32,
border_radius: f32,
border_radius: BorderRadius,
clip_mode: BoxShadowClipMode,
) {
let item = SpecificDisplayItem::BoxShadow(BoxShadowDisplayItem {

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

@ -151,7 +151,7 @@ pub trait BlobImageResources {
pub trait BlobImageRenderer: Send {
fn add(&mut self, key: ImageKey, data: BlobImageData, tiling: Option<TileSize>);
fn update(&mut self, key: ImageKey, data: BlobImageData);
fn update(&mut self, key: ImageKey, data: BlobImageData, dirty_rect: Option<DeviceUintRect>);
fn delete(&mut self, key: ImageKey);

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

@ -13,8 +13,6 @@ extern crate byteorder;
#[cfg(feature = "nightly")]
extern crate core;
extern crate euclid;
#[macro_use]
extern crate heapsize;
#[cfg(feature = "ipc")]
extern crate ipc_channel;
#[macro_use]

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

@ -5,7 +5,7 @@ authors = ["The Mozilla Project Developers"]
license = "MPL-2.0"
[dependencies]
webrender_api = {path = "../webrender_api", version = "0.52.1"}
webrender_api = {path = "../webrender_api", version = "0.53.0"}
bincode = "0.8"
rayon = "0.8"
thread_profiler = "0.1.1"
@ -15,5 +15,5 @@ gleam = "0.4"
[dependencies.webrender]
path = "../webrender"
version = "0.52.1"
version = "0.53.0"
default-features = false

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

@ -325,6 +325,7 @@ static inline wr::ComplexClipRegion ToComplexClipRegion(const RoundedRect& rect)
ret.radii.top_right = ToLayoutSize(LayoutDeviceSize::FromUnknownSize(rect.corners.radii[mozilla::eCornerTopRight]));
ret.radii.bottom_left = ToLayoutSize(LayoutDeviceSize::FromUnknownSize(rect.corners.radii[mozilla::eCornerBottomLeft]));
ret.radii.bottom_right = ToLayoutSize(LayoutDeviceSize::FromUnknownSize(rect.corners.radii[mozilla::eCornerBottomRight]));
ret.mode = wr::ClipMode::Clip;
return ret;
}

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

@ -418,20 +418,26 @@ extern "C" {
}
impl webrender_api::RenderNotifier for CppNotifier {
fn new_frame_ready(&mut self) {
fn clone(&self) -> Box<webrender_api::RenderNotifier> {
Box::new(CppNotifier {
window_id: self.window_id,
})
}
fn new_frame_ready(&self) {
unsafe {
wr_notifier_new_frame_ready(self.window_id);
}
}
fn new_scroll_frame_ready(&mut self,
fn new_scroll_frame_ready(&self,
composite_needed: bool) {
unsafe {
wr_notifier_new_scroll_frame_ready(self.window_id, composite_needed);
}
}
fn external_event(&mut self,
fn external_event(&self,
event: ExternalEvent) {
unsafe {
wr_notifier_external_event(self.window_id, event.unwrap());
@ -643,7 +649,10 @@ pub extern "C" fn wr_window_new(window_id: WrWindowId,
..Default::default()
};
let (renderer, sender) = match Renderer::new(gl, opts) {
let notifier = Box::new(CppNotifier {
window_id: window_id,
});
let (renderer, sender) = match Renderer::new(gl, notifier, opts) {
Ok((renderer, sender)) => (renderer, sender),
Err(e) => {
println!(" Failed to create a Renderer: {:?}", e);
@ -655,9 +664,6 @@ pub extern "C" fn wr_window_new(window_id: WrWindowId,
},
};
renderer.set_render_notifier(Box::new(CppNotifier {
window_id: window_id,
}));
unsafe {
*out_max_texture_size = renderer.get_max_texture_size();
}
@ -1726,7 +1732,7 @@ pub extern "C" fn wr_dp_push_box_shadow(state: &mut WrState,
color,
blur_radius,
spread_radius,
border_radius,
BorderRadius::uniform(border_radius),
clip_mode);
}

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

@ -31,7 +31,7 @@ impl BlobImageRenderer for Moz2dImageRenderer {
self.blob_commands.insert(key, (Arc::new(data), tiling));
}
fn update(&mut self, key: ImageKey, data: BlobImageData) {
fn update(&mut self, key: ImageKey, data: BlobImageData, _dirty_rect: Option<DeviceUintRect>) {
let entry = self.blob_commands.get_mut(&key).unwrap();
entry.0 = Arc::new(data);
}

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

@ -41,6 +41,13 @@ enum class BoxShadowClipMode : uint32_t {
Sentinel /* this must be last for serialization purposes. */
};
enum class ClipMode {
Clip = 0,
ClipOut = 1,
Sentinel /* this must be last for serialization purposes. */
};
enum class ExtendMode : uint32_t {
Clamp = 0,
Repeat = 1,
@ -450,10 +457,14 @@ struct ComplexClipRegion {
LayoutRect rect;
// Border radii of this rectangle.
BorderRadius radii;
// Whether we are clipping inside or outside
// the region.
ClipMode mode;
bool operator==(const ComplexClipRegion& aOther) const {
return rect == aOther.rect &&
radii == aOther.radii;
radii == aOther.radii &&
mode == aOther.mode;
}
};

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

@ -227,10 +227,39 @@ LocaleService::GetRegionalPrefsLocales(nsTArray<nsCString>& aRetVal)
{
bool useOSLocales = Preferences::GetBool("intl.regional_prefs.use_os_locales", false);
if (useOSLocales && OSPreferences::GetInstance()->GetRegionalPrefsLocales(aRetVal)) {
// If the user specified that they want to use OS Regional Preferences locales,
// try to retrieve them and use.
if (useOSLocales) {
if (OSPreferences::GetInstance()->GetRegionalPrefsLocales(aRetVal)) {
return;
}
// If we fail to retrieve them, return the app locales.
GetAppLocalesAsBCP47(aRetVal);
return;
}
// Otherwise, fetch OS Regional Preferences locales and compare the first one
// to the app locale. If the language subtag matches, we can safely use
// the OS Regional Preferences locale.
//
// This facilitates scenarios such as Firefox in "en-US" and User sets
// regional prefs to "en-GB".
nsAutoCString appLocale;
AutoTArray<nsCString, 10> regionalPrefsLocales;
LocaleService::GetInstance()->GetAppLocaleAsBCP47(appLocale);
if (!OSPreferences::GetInstance()->GetRegionalPrefsLocales(regionalPrefsLocales)) {
GetAppLocalesAsBCP47(aRetVal);
return;
}
if (LocaleService::LanguagesMatch(appLocale, regionalPrefsLocales[0])) {
aRetVal = regionalPrefsLocales;
return;
}
// Otherwise use the app locales.
GetAppLocalesAsBCP47(aRetVal);
}

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

@ -170,7 +170,9 @@ OSPreferences::GetDateTimePatternForStyle(DateTimeFormatStyle aDateStyle,
nsAutoCString locale;
if (aLocale.IsEmpty()) {
LocaleService::GetInstance()->GetAppLocaleAsBCP47(locale);
AutoTArray<nsCString, 10> regionalPrefsLocales;
LocaleService::GetInstance()->GetRegionalPrefsLocales(regionalPrefsLocales);
locale.Assign(regionalPrefsLocales[0]);
} else {
locale.Assign(aLocale);
}

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

@ -52,25 +52,6 @@ OSPreferences::ReadRegionalPrefsLocales(nsTArray<nsCString>& aLocaleList)
return false;
}
/**
* Windows distinguishes between System Locale (the locale OS is in), and
* User Locale (the locale used for regional settings etc.).
*
* For DateTimePattern, we want to retrieve the User Locale.
*/
static void
ReadUserLocale(nsCString& aRetVal)
{
WCHAR locale[LOCALE_NAME_MAX_LENGTH];
if (NS_WARN_IF(!LCIDToLocaleName(LOCALE_USER_DEFAULT, locale,
LOCALE_NAME_MAX_LENGTH, 0))) {
aRetVal.AssignLiteral("en-US");
return;
}
LossyCopyUTF16toASCII(locale, aRetVal);
}
static LCTYPE
ToDateLCType(OSPreferences::DateTimeFormatStyle aFormatStyle)
{
@ -113,29 +94,6 @@ ToTimeLCType(OSPreferences::DateTimeFormatStyle aFormatStyle)
}
}
LPWSTR
GetWindowsLocaleFor(const nsACString& aLocale, LPWSTR aBuffer)
{
nsAutoCString reqLocale;
nsAutoCString userLocale;
ReadUserLocale(userLocale);
if (aLocale.IsEmpty()) {
LocaleService::GetInstance()->GetAppLocaleAsBCP47(reqLocale);
} else {
reqLocale.Assign(aLocale);
}
bool match = LocaleService::LanguagesMatch(reqLocale, userLocale);
if (match || reqLocale.Length() >= LOCALE_NAME_MAX_LENGTH) {
UTF8ToUnicodeBuffer(userLocale, (char16_t*)aBuffer);
} else {
UTF8ToUnicodeBuffer(reqLocale, (char16_t*)aBuffer);
}
return aBuffer;
}
/**
* Windows API includes regional preferences from the user only
* if we pass empty locale string or if the locale string matches
@ -158,9 +116,8 @@ OSPreferences::ReadDateTimePattern(DateTimeFormatStyle aDateStyle,
DateTimeFormatStyle aTimeStyle,
const nsACString& aLocale, nsAString& aRetVal)
{
WCHAR buffer[LOCALE_NAME_MAX_LENGTH];
LPWSTR localeName = GetWindowsLocaleFor(aLocale, buffer);
WCHAR localeName[LOCALE_NAME_MAX_LENGTH];
UTF8ToUnicodeBuffer(aLocale, (char16_t*)localeName);
bool isDate = aDateStyle != DateTimeFormatStyle::None &&
aDateStyle != DateTimeFormatStyle::Invalid;

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

@ -232,7 +232,7 @@ nsStringBundle::GetCombinedEnumeration(nsIStringBundleOverride* aOverrideStrings
rv = overrideEnumerator->GetNext(getter_AddRefs(supports));
if (NS_SUCCEEDED(rv))
resultArray->AppendElement(supports, false);
resultArray->AppendElement(supports);
rv = overrideEnumerator->HasMoreElements(&hasMore);
NS_ENSURE_SUCCESS(rv, rv);
@ -261,7 +261,7 @@ nsStringBundle::GetCombinedEnumeration(nsIStringBundleOverride* aOverrideStrings
// if it isn't there, then it is safe to append
if (NS_FAILED(rv))
resultArray->AppendElement(propElement, false);
resultArray->AppendElement(propElement);
}
rv = propEnumerator->HasMoreElements(&hasMore);

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

@ -1868,7 +1868,8 @@ PresShell::AsyncResizeEventCallback(nsITimer* aTimer, void* aPresShell)
}
nsresult
PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight, nscoord aOldWidth, nscoord aOldHeight)
PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight, nscoord aOldWidth,
nscoord aOldHeight, ResizeReflowOptions aOptions)
{
if (mZoomConstraintsClient) {
// If we have a ZoomConstraintsClient and the available screen area
@ -1884,38 +1885,58 @@ PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight, nscoord aOldWidth, nsco
return NS_OK;
}
return ResizeReflowIgnoreOverride(aWidth, aHeight, aOldWidth, aOldHeight);
return ResizeReflowIgnoreOverride(aWidth, aHeight, aOldWidth,
aOldHeight, aOptions);
}
nsresult
PresShell::ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight, nscoord aOldWidth, nscoord aOldHeight)
PresShell::ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight,
nscoord aOldWidth, nscoord aOldHeight,
ResizeReflowOptions aOptions)
{
NS_PRECONDITION(!mIsReflowing, "Shouldn't be in reflow here!");
// If we don't have a root frame yet, that means we haven't had our initial
// reflow... If that's the case, and aWidth or aHeight is unconstrained,
// ignore them altogether.
nsIFrame* rootFrame = mFrameConstructor->GetRootFrame();
if (!rootFrame && aHeight == NS_UNCONSTRAINEDSIZE) {
// We can't do the work needed for SizeToContent without a root
// frame, and we want to return before setting the visible area.
return NS_ERROR_NOT_AVAILABLE;
}
mPresContext->SetVisibleArea(nsRect(0, 0, aWidth, aHeight));
// There isn't anything useful we can do if the initial reflow hasn't happened.
if (!rootFrame) {
// If we don't have a root frame yet, that means we haven't had our initial
// reflow... If that's the case, and aWidth or aHeight is unconstrained,
// ignore them altogether.
if (aHeight == NS_UNCONSTRAINEDSIZE || aWidth == NS_UNCONSTRAINEDSIZE) {
// We can't do the work needed for SizeToContent without a root
// frame, and we want to return before setting the visible area.
return NS_ERROR_NOT_AVAILABLE;
}
mPresContext->SetVisibleArea(nsRect(0, 0, aWidth, aHeight));
// There isn't anything useful we can do if the initial reflow hasn't
// happened.
return NS_OK;
}
WritingMode wm = rootFrame->GetWritingMode();
NS_PRECONDITION((wm.IsVertical() ? aHeight : aWidth) != NS_UNCONSTRAINEDSIZE,
"shouldn't use unconstrained isize anymore");
const bool shrinkToFit = aOptions == ResizeReflowOptions::eBSizeLimit;
NS_PRECONDITION(shrinkToFit ||
(wm.IsVertical() ? aWidth : aHeight) !=
NS_UNCONSTRAINEDSIZE,
"unconstrained bsize only usable with eBSizeLimit");
NS_PRECONDITION((wm.IsVertical() ? aHeight : aWidth) !=
NS_UNCONSTRAINEDSIZE,
"unconstrained isize not allowed");
bool isBSizeChanging = wm.IsVertical() ? aOldWidth != aWidth
: aOldHeight != aHeight;
nscoord targetWidth = aWidth;
nscoord targetHeight = aHeight;
const bool isBSizeChanging = wm.IsVertical()
? aOldWidth != aWidth
: aOldHeight != aHeight;
if (shrinkToFit) {
if (wm.IsVertical()) {
targetWidth = NS_UNCONSTRAINEDSIZE;
} else {
targetHeight = NS_UNCONSTRAINEDSIZE;
}
isBSizeChanging = true;
}
mPresContext->SetVisibleArea(nsRect(0, 0, targetWidth, targetHeight));
RefPtr<nsViewManager> viewManager = mViewManager;
nsCOMPtr<nsIPresShell> kungFuDeathGrip(this);
@ -1954,8 +1975,29 @@ PresShell::ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight, nscoord a
mDirtyRoots.RemoveElement(rootFrame);
DoReflow(rootFrame, true);
if (shrinkToFit) {
const bool reflowAgain = wm.IsVertical() ?
mPresContext->GetVisibleArea().width > aWidth :
mPresContext->GetVisibleArea().height > aHeight;
if (reflowAgain) {
mPresContext->SetVisibleArea(nsRect(0, 0, aWidth, aHeight));
DoReflow(rootFrame, true);
}
}
}
// the first DoReflow above should've set our bsize if it was
// NS_UNCONSTRAINEDSIZE, and the isize shouldn't be NS_UNCONSTRAINEDSIZE
// anyway
NS_ASSERTION(
mPresContext->GetVisibleArea().width != NS_UNCONSTRAINEDSIZE,
"width should not be NS_UNCONSTRAINEDSIZE after reflow");
NS_ASSERTION(
mPresContext->GetVisibleArea().height != NS_UNCONSTRAINEDSIZE,
"height should not be NS_UNCONSTRAINEDSIZE after reflow");
DidDoReflow(true);
}
}
@ -1963,13 +2005,16 @@ PresShell::ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight, nscoord a
rootFrame = mFrameConstructor->GetRootFrame();
if (rootFrame) {
wm = rootFrame->GetWritingMode();
// reflow did not happen; if the reflow happened, our bsize should not be
// NS_UNCONSTRAINEDSIZE because DoReflow will fix it up to the same values
// as below
if (wm.IsVertical()) {
if (aWidth == NS_UNCONSTRAINEDSIZE) {
if (mPresContext->GetVisibleArea().width == NS_UNCONSTRAINEDSIZE) {
mPresContext->SetVisibleArea(
nsRect(0, 0, rootFrame->GetRect().width, aHeight));
}
} else {
if (aHeight == NS_UNCONSTRAINEDSIZE) {
if (mPresContext->GetVisibleArea().height == NS_UNCONSTRAINEDSIZE) {
mPresContext->SetVisibleArea(
nsRect(0, 0, aWidth, rootFrame->GetRect().height));
}
@ -1991,7 +2036,7 @@ PresShell::ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight, nscoord a
nsITimer::TYPE_ONE_SHOT,
"AsyncResizeEventCallback");
}
} else {
} else if (mPresContext->ShouldFireResizeEvent()) {
RefPtr<nsRunnableMethod<PresShell>> event = NewRunnableMethod(
"PresShell::FireResizeEvent", this, &PresShell::FireResizeEvent);
nsresult rv = mDocument->Dispatch(TaskCategory::Other,
@ -1999,6 +2044,7 @@ PresShell::ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight, nscoord a
if (NS_SUCCEEDED(rv)) {
mResizeEvent = Move(event);
SetNeedStyleFlush();
mPresContext->WillFireResizeEvent();
}
}
}

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

@ -111,8 +111,14 @@ public:
virtual void BeginObservingDocument() override;
virtual void EndObservingDocument() override;
virtual nsresult Initialize(nscoord aWidth, nscoord aHeight) override;
virtual nsresult ResizeReflow(nscoord aWidth, nscoord aHeight, nscoord aOldWidth = 0, nscoord aOldHeight = 0) override;
virtual nsresult ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight, nscoord aOldWidth, nscoord aOldHeight) override;
virtual nsresult ResizeReflow(nscoord aWidth, nscoord aHeight,
nscoord aOldWidth = 0, nscoord aOldHeight = 0,
ResizeReflowOptions aOptions =
ResizeReflowOptions::eBSizeExact) override;
virtual nsresult ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight,
nscoord aOldWidth, nscoord aOldHeight,
ResizeReflowOptions aOptions =
ResizeReflowOptions::eBSizeExact) override;
virtual nsIPageSequenceFrame* GetPageSequenceFrame() const override;
virtual nsCanvasFrame* GetCanvasFrame() const override;

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

@ -267,7 +267,7 @@ load 448543-1.html
load 448543-2.html
load 448543-3.html
load 450319-1.xhtml
asserts(1) load 453894-1.xhtml # Bug 398043
asserts(1) asserts-if(stylo&&Android,2) load 453894-1.xhtml # Bug 398043
load 454751-1.xul
load 455063-1.html
load 455063-2.html

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

@ -3508,37 +3508,16 @@ nsDocumentViewer::GetContentSizeInternal(int32_t* aWidth, int32_t* aHeight,
prefWidth = aMaxWidth;
}
nsAutoPtr<nsPresState> frameState;
nsIScrollableFrame *scrollFrame = presShell->GetRootScrollFrameAsScrollable();
nsIStatefulFrame *statefulFrame = do_QueryFrame(scrollFrame);
if (statefulFrame) {
statefulFrame->SaveState(getter_Transfers(frameState));
}
nsresult rv = presShell->ResizeReflow(prefWidth, NS_UNCONSTRAINEDSIZE);
nsresult rv = presShell->ResizeReflow(prefWidth, aMaxHeight, 0, 0,
nsIPresShell::ResizeReflowOptions::eBSizeLimit);
NS_ENSURE_SUCCESS(rv, rv);
RefPtr<nsPresContext> presContext;
GetPresContext(getter_AddRefs(presContext));
NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
// so how big is it?
nsRect shellArea = presContext->GetVisibleArea();
if (shellArea.height > aMaxHeight) {
// Reflow to max height if we would up too tall.
rv = presShell->ResizeReflow(prefWidth, aMaxHeight);
NS_ENSURE_SUCCESS(rv, rv);
shellArea = presContext->GetVisibleArea();
// the first reflow reset our scroll, now set it back
if (frameState && presShell->GetRootScrollFrameAsScrollable() == scrollFrame) {
statefulFrame->RestoreState(frameState);
scrollFrame->ScrollToRestoredPosition();
}
}
// Protect against bogus returns here
nsRect shellArea = presContext->GetVisibleArea();
NS_ENSURE_TRUE(shellArea.width != NS_UNCONSTRAINEDSIZE &&
shellArea.height != NS_UNCONSTRAINEDSIZE,
NS_ERROR_FAILURE);

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

@ -359,16 +359,30 @@ public:
*/
virtual nsresult Initialize(nscoord aWidth, nscoord aHeight) = 0;
enum class ResizeReflowOptions : uint32_t {
// the resulting BSize should be exactly as given
eBSizeExact,
// the resulting BSize can be less than the given one, producing
// shrink-to-fit sizing in the block dimension
eBSizeLimit
};
/**
* Reflow the frame model into a new width and height. The
* coordinates for aWidth and aHeight must be in standard nscoord's.
*/
virtual nsresult ResizeReflow(nscoord aWidth, nscoord aHeight, nscoord aOldWidth = 0, nscoord aOldHeight = 0) = 0;
virtual nsresult ResizeReflow(nscoord aWidth, nscoord aHeight,
nscoord aOldWidth = 0, nscoord aOldHeight = 0,
ResizeReflowOptions aOptions =
ResizeReflowOptions::eBSizeExact) = 0;
/**
* Do the same thing as ResizeReflow but even if ResizeReflowOverride was
* called previously.
*/
virtual nsresult ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight, nscoord aOldWidth, nscoord aOldHeight) = 0;
virtual nsresult ResizeReflowIgnoreOverride(
nscoord aWidth, nscoord aHeight,
nscoord aOldWidth, nscoord aOldHeight,
ResizeReflowOptions aOptions =
ResizeReflowOptions::eBSizeExact) = 0;
/**
* Returns true if ResizeReflowOverride has been called.

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