зеркало из https://github.com/mozilla/gecko-dev.git
merge autoland to mozilla-central. r=merge a=merge
MozReview-Commit-ID: 4FPQxtXkXoF
This commit is contained in:
Коммит
0021c0caf6
|
@ -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(¬ifier),
|
||||
notifier: notifier.clone(),
|
||||
};
|
||||
|
||||
let mut device = Device::new(
|
||||
|
@ -1652,7 +1649,7 @@ impl Renderer {
|
|||
|
||||
device.end_frame();
|
||||
|
||||
let backend_notifier = Arc::clone(¬ifier);
|
||||
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.
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче