Merge m-c to autoland, a=merge

MozReview-Commit-ID: 6CUQEJghjzU
This commit is contained in:
Wes Kocher 2017-04-27 13:37:47 -07:00
Родитель b27ac0ada8 2aa72d4cdc
Коммит a463bb4c4c
263 изменённых файлов: 25610 добавлений и 21400 удалений

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

@ -261,7 +261,7 @@ js/src/jit-test/**
js/src/tests/**
# mobile/android/ exclusions
mobile/android/tests/
mobile/android/tests/browser/chrome/tp5/**
# Uses `#filter substitution`
mobile/android/b2gdroid/app/b2gdroid.js

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

@ -5,6 +5,8 @@ const ID_ICON = "update_icon2@tests.mozilla.org";
const ID_PERMS = "update_perms@tests.mozilla.org";
const ID_LEGACY = "legacy_update@tests.mozilla.org";
requestLongerTimeout(2);
function promiseViewLoaded(tab, viewid) {
let win = tab.linkedBrowser.contentWindow;
if (win.gViewController && !win.gViewController.isLoading &&

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

@ -1,2 +1,3 @@
[DEFAULT]
[browser_toolbariconcolor_restyles.js]
skip-if = os == "mac" && debug # Bug 1358356

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

@ -53,5 +53,6 @@ tags = geolocation
[browser_privatebrowsing_zoom.js]
[browser_privatebrowsing_zoomrestore.js]
[browser_privatebrowsing_newtab_from_popup.js]
skip-if = (!e10s && os == "win" && (bits == 64)) # Bug 1354865
[browser_privatebrowsing_blobUrl.js]
[browser_oa_private_browsing_window.js]

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

@ -3708,6 +3708,7 @@ var SessionStoreInternal = {
formdata: tabData.formdata || null,
disallow: tabData.disallow || null,
pageStyle: tabData.pageStyle || null,
userContextId: tabData.userContextId || 0,
// This information is only needed until the tab has finished restoring.
// When that's done it will be removed from the cache and we always

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

@ -78,7 +78,7 @@ function isWS({ requestHeaders, responseHeaders }) {
// Find the 'upgrade' header.
let upgradeHeader = requestHeaders.headers.find(header => {
return (header.name == "Upgrade");
return (header.name.toLowerCase() == "upgrade");
});
// If no header found on request, check response - mainly to get
@ -87,7 +87,7 @@ function isWS({ requestHeaders, responseHeaders }) {
if (!upgradeHeader && responseHeaders &&
Array.isArray(responseHeaders.headers)) {
upgradeHeader = responseHeaders.headers.find(header => {
return (header.name == "Upgrade");
return (header.name.toLowerCase() == "upgrade");
});
}

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

@ -54,12 +54,12 @@ add_task(function* () {
const EXPECTED_RESPONSE_HEADERS = [
`${httpVersion} ${status} ${statusText}`,
"Last-Modified: Sun, 3 May 2015 11:11:11 GMT",
"Content-Type: text/html",
"Content-Length: 465",
"Connection: close",
"Server: httpd.js",
"Date: Sun, 3 May 2015 11:11:11 GMT"
"last-modified: Sun, 3 May 2015 11:11:11 GMT",
"content-type: text/html",
"content-length: 465",
"connection: close",
"server: httpd.js",
"date: Sun, 3 May 2015 11:11:11 GMT"
].join("\n");
EventUtils.sendMouseEvent({ type: "contextmenu" },
@ -71,8 +71,8 @@ add_task(function* () {
}, function validate(result) {
// Fake the "Last-Modified" and "Date" headers because they will vary:
result = String(result)
.replace(/Last-Modified: [^\n]+ GMT/, "Last-Modified: Sun, 3 May 2015 11:11:11 GMT")
.replace(/Date: [^\n]+ GMT/, "Date: Sun, 3 May 2015 11:11:11 GMT");
.replace(/last-modified: [^\n]+ GMT/, "last-modified: Sun, 3 May 2015 11:11:11 GMT")
.replace(/date: [^\n]+ GMT/, "date: Sun, 3 May 2015 11:11:11 GMT");
return result === EXPECTED_RESPONSE_HEADERS;
});
info("Clipboard contains the currently selected item's response headers.");

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

@ -325,14 +325,15 @@ add_task(function* () {
const visibleItems = getDisplayedRequests(gStore.getState());
is(items.size, visibility.length,
"There should be a specific amount of items in the requests menu.");
"There should be a specific amount of items in the requests menu.");
is(visibleItems.size, visibility.filter(e => e).length,
"There should be a specific amount of visible items in the requests menu.");
"There should be a specific amount of visible items in the requests menu.");
for (let i = 0; i < visibility.length; i++) {
let itemId = items.get(i).id;
let shouldBeVisible = !!visibility[i];
let isThere = visibleItems.some(r => r.id == itemId);
is(isThere, shouldBeVisible,
`The item at index ${i} has visibility=${shouldBeVisible}`);

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

@ -55,9 +55,9 @@ add_task(function* () {
let lastRequest = getSortedRequests(gStore.getState()).get(1);
info("First request happened at: " +
firstRequest.responseHeaders.headers.find(e => e.name == "Date").value);
firstRequest.responseHeaders.headers.find(e => e.name == "date").value);
info("Last request happened at: " +
lastRequest.responseHeaders.headers.find(e => e.name == "Date").value);
lastRequest.responseHeaders.headers.find(e => e.name == "date").value);
ok(secDivs.length,
"There should be at least one division on the seconds time scale.");

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

@ -86,7 +86,7 @@ AppCacheUtils.prototype = {
_parseManifest: function ACU__parseManifest(uriInfo) {
let deferred = defer();
let manifestName = uriInfo.name;
let manifestLastModified = new Date(uriInfo.responseHeaders["Last-Modified"]);
let manifestLastModified = new Date(uriInfo.responseHeaders["last-modified"]);
if (uriInfo.charset.toLowerCase() != "utf-8") {
this._addError(0, "notUTF8", uriInfo.charset);
@ -158,7 +158,7 @@ AppCacheUtils.prototype = {
// Check that the resource was not modified after the manifest was last
// modified. If it was then the manifest file should be refreshed.
let resourceLastModified =
new Date(uriInfo.responseHeaders["Last-Modified"]);
new Date(uriInfo.responseHeaders["last-modified"]);
if (manifestLastModified < resourceLastModified) {
this._addError(parsedUri.line, "fileChangedButNotManifest",
@ -230,12 +230,12 @@ AppCacheUtils.prototype = {
result.requestHeaders = {};
request.visitRequestHeaders(function (header, value) {
result.requestHeaders[header] = value;
result.requestHeaders[header.toLowerCase()] = value;
});
result.responseHeaders = {};
request.visitResponseHeaders(function (header, value) {
result.responseHeaders[header] = value;
result.responseHeaders[header.toLowerCase()] = value;
});
deferred.resolve(result);

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

@ -81,14 +81,14 @@ const Curl = {
postDataText = data.postDataText;
postData.push("--data");
postData.push(escapeString(utils.writePostDataTextParams(postDataText)));
ignoredHeaders.add("Content-Length");
ignoredHeaders.add("content-length");
} else if (multipartRequest) {
postDataText = data.postDataText;
postData.push("--data-binary");
let boundary = utils.getMultipartBoundary(data);
let text = utils.removeBinaryDataFromMultipartText(postDataText, boundary);
postData.push(escapeString(text));
ignoredHeaders.add("Content-Length");
ignoredHeaders.add("content-length");
}
// Add method.
@ -119,11 +119,11 @@ const Curl = {
}
for (let i = 0; i < headers.length; i++) {
let header = headers[i];
if (header.name === "Accept-Encoding") {
if (header.name.toLowerCase() === "accept-encoding") {
command.push("--compressed");
continue;
}
if (ignoredHeaders.has(header.name)) {
if (ignoredHeaders.has(header.name.toLowerCase())) {
continue;
}
command.push("-H");

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

@ -26,11 +26,11 @@ add_task(function* () {
// Select "Headers" tab
let tabBody = yield selectNetInfoTab(hud, netInfoBody, "headers");
let paramName = tabBody.querySelector(
".netInfoParamName > span[title='Content-Type']");
".netInfoParamName > span[title='content-type']");
// Verify "Content-Type" header (name and value)
ok(paramName, "Header name must exist");
is(paramName.textContent, "Content-Type",
is(paramName.textContent, "content-type",
"The header name must have proper value");
let paramValue = paramName.parentNode.nextSibling;

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

@ -87,7 +87,7 @@ function getContent() {
function performTest() {
function readHeader(name) {
for (let header of headers) {
if (header.name == name) {
if (header.name.toLowerCase() == name.toLowerCase()) {
return header.value;
}
}

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

@ -196,13 +196,13 @@ function onResponseHeaders(aState, aResponse)
ok(!!aResponse.rawHeaders, "response rawHeaders available");
checkHeadersOrCookies(aResponse.headers, {
"Content-Type": /^application\/(json|octet-stream)$/,
"Content-Length": /^\d+$/,
"content-type": /^application\/(json|octet-stream)$/,
"content-length": /^\d+$/,
});
checkRawHeaders(aResponse.rawHeaders, {
"Content-Type": /^application\/(json|octet-stream)$/,
"Content-Length": /^\d+$/,
"content-type": /^application\/(json|octet-stream)$/,
"content-length": /^\d+$/,
});
onResponseCookies = onResponseCookies.bind(null, aState);

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

@ -212,8 +212,8 @@ function onResponseHeaders(aState, aResponse)
ok(aResponse.headersSize > 0, "response headersSize > 0");
checkHeadersOrCookies(aResponse.headers, {
"Content-Type": /^application\/(json|octet-stream)$/,
"Content-Length": /^\d+$/,
"content-type": /^application\/(json|octet-stream)$/,
"content-length": /^\d+$/,
"x-very-short": "hello world",
"x-very-long": {
"type": "longString",

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

@ -204,13 +204,13 @@ function onResponseHeaders(aState, aResponse)
ok(!!aResponse.rawHeaders, "response rawHeaders available");
checkHeadersOrCookies(aResponse.headers, {
"Content-Type": /^application\/(json|octet-stream)$/,
"Content-Length": /^\d+$/,
"content-type": /^application\/(json|octet-stream)$/,
"content-length": /^\d+$/,
});
checkRawHeaders(aResponse.rawHeaders, {
"Content-Type": /^application\/(json|octet-stream)$/,
"Content-Length": /^\d+$/,
"content-type": /^application\/(json|octet-stream)$/,
"content-length": /^\d+$/,
});
onResponseCookies = onResponseCookies.bind(null, aState);

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

@ -80,6 +80,7 @@ nsDOMNavigationTiming::NotifyNavigationStart(DocShellState aDocShellState)
mNavigationStartHighRes = (double)PR_Now() / PR_USEC_PER_MSEC;
mNavigationStartTimeStamp = TimeStamp::Now();
mDocShellHasBeenActiveSinceNavigationStart = (aDocShellState == DocShellState::eActive);
PROFILER_MARKER("Navigation::Start");
}
void
@ -108,12 +109,14 @@ void
nsDOMNavigationTiming::NotifyUnloadEventStart()
{
mUnloadStart = DurationFromStart();
profiler_tracing("Navigation", "Unload", TRACING_INTERVAL_START);
}
void
nsDOMNavigationTiming::NotifyUnloadEventEnd()
{
mUnloadEnd = DurationFromStart();
profiler_tracing("Navigation", "Unload", TRACING_INTERVAL_END);
}
void
@ -123,6 +126,8 @@ nsDOMNavigationTiming::NotifyLoadEventStart()
mLoadEventStart = DurationFromStart();
mLoadEventStartSet = true;
profiler_tracing("Navigation", "Load", TRACING_INTERVAL_START);
if (IsTopLevelContentDocument()) {
Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_LOAD_EVENT_START_MS,
mNavigationStartTimeStamp);
@ -137,6 +142,8 @@ nsDOMNavigationTiming::NotifyLoadEventEnd()
mLoadEventEnd = DurationFromStart();
mLoadEventEndSet = true;
profiler_tracing("Navigation", "Load", TRACING_INTERVAL_END);
if (IsTopLevelContentDocument()) {
Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_LOAD_EVENT_END_MS,
mNavigationStartTimeStamp);
@ -162,6 +169,8 @@ nsDOMNavigationTiming::NotifyDOMLoading(nsIURI* aURI)
mDOMLoading = DurationFromStart();
mDOMLoadingSet = true;
PROFILER_MARKER("Navigation::DOMLoading");
if (IsTopLevelContentDocument()) {
Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_DOM_LOADING_MS,
mNavigationStartTimeStamp);
@ -177,6 +186,8 @@ nsDOMNavigationTiming::NotifyDOMInteractive(nsIURI* aURI)
mDOMInteractive = DurationFromStart();
mDOMInteractiveSet = true;
PROFILER_MARKER("Navigation::DOMInteractive");
if (IsTopLevelContentDocument()) {
Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_DOM_INTERACTIVE_MS,
mNavigationStartTimeStamp);
@ -192,6 +203,8 @@ nsDOMNavigationTiming::NotifyDOMComplete(nsIURI* aURI)
mDOMComplete = DurationFromStart();
mDOMCompleteSet = true;
PROFILER_MARKER("Navigation::DOMComplete");
if (IsTopLevelContentDocument()) {
Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_DOM_COMPLETE_MS,
mNavigationStartTimeStamp);
@ -207,6 +220,8 @@ nsDOMNavigationTiming::NotifyDOMContentLoadedStart(nsIURI* aURI)
mDOMContentLoadedEventStart = DurationFromStart();
mDOMContentLoadedEventStartSet = true;
profiler_tracing("Navigation", "DOMContentLoaded", TRACING_INTERVAL_START);
if (IsTopLevelContentDocument()) {
Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_DOM_CONTENT_LOADED_START_MS,
mNavigationStartTimeStamp);
@ -222,6 +237,8 @@ nsDOMNavigationTiming::NotifyDOMContentLoadedEnd(nsIURI* aURI)
mDOMContentLoadedEventEnd = DurationFromStart();
mDOMContentLoadedEventEndSet = true;
profiler_tracing("Navigation", "DOMContentLoaded", TRACING_INTERVAL_END);
if (IsTopLevelContentDocument()) {
Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_DOM_CONTENT_LOADED_END_MS,
mNavigationStartTimeStamp);

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

@ -34,7 +34,7 @@ function runTests() {
storage = t.storage;
var ifr = document.getElementById("iframe");
ifr.src = "data:text/html,<script>" + t.key + ".setItem(\"a\",\"b\");</" + "script>";
ifr.srcdoc = "<script>"+ t.key + ".setItem(\"a\",\"b\");</"+"script>";
}
SimpleTest.waitForExplicitFinish();

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

@ -21,8 +21,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1101364
</head>
<body id='body'>
<iframe id="test1" src="data:text/html,<h1 id='test1' style='-moz-user-select:none'>Header</h1><div id='testDiv'>test1</div>"></iframe>
<iframe id="test2" src="data:text/html,<div contenteditable id='test2'>AAA<span id='test2Inner'>BBB</span></div>"></iframe>
<iframe id="test1" srcdoc="<h1 id='test1' style='-moz-user-select:none'>Header</h1><div id='testDiv'>test1</div>"></iframe>
<iframe id="test2" srcdoc="<div contenteditable id='test2'>AAA<span id='test2Inner'>BBB</span></div>"></iframe>
<pre id="test">
<script class="testbody" type="text/javascript">

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

@ -5271,6 +5271,18 @@ ContentParent::RecvClassifyLocal(const URIParams& aURI, const nsCString& aTables
return IPC_OK();
}
mozilla::ipc::IPCResult
ContentParent::RecvAllocPipelineId(RefPtr<AllocPipelineIdPromise>&& aPromise)
{
GPUProcessManager* pm = GPUProcessManager::Get();
if (!pm) {
aPromise->Reject(PromiseRejectReason::HandlerRejected, __func__);
return IPC_OK();
}
aPromise->Resolve(wr::AsPipelineId(pm->AllocateLayerTreeId()), __func__);
return IPC_OK();
}
mozilla::ipc::IPCResult
ContentParent::RecvFileCreationRequest(const nsID& aID,
const nsString& aFullPath,

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

@ -646,6 +646,9 @@ public:
nsresult* aRv,
nsTArray<nsCString>* aResults) override;
virtual mozilla::ipc::IPCResult
RecvAllocPipelineId(RefPtr<AllocPipelineIdPromise>&& aPromise) override;
// Use the PHangMonitor channel to ask the child to repaint a tab.
void ForceTabPaint(TabParent* aTabParent, uint64_t aLayerObserverEpoch);

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

@ -64,6 +64,7 @@ include MemoryReportTypes;
// are put into different UnifiedProtocolsXX.cpp files.
// XXX Remove this once bug 1069073 is fixed
include "mozilla/dom/PContentBridgeParent.h";
include "mozilla/layers/WebRenderMessageUtils.h";
using GeoPosition from "nsGeoPositionIPCSerialiser.h";
using AlertNotificationType from "mozilla/AlertNotificationIPCSerializer.h";
@ -96,6 +97,7 @@ using mozilla::Telemetry::KeyedAccumulation from "mozilla/TelemetryComms.h";
using mozilla::Telemetry::ScalarAction from "mozilla/TelemetryComms.h";
using mozilla::Telemetry::KeyedScalarAction from "mozilla/TelemetryComms.h";
using mozilla::Telemetry::ChildEventData from "mozilla/TelemetryComms.h";
using mozilla::wr::PipelineId from "mozilla/webrender/WebRenderTypes.h";
union ChromeRegistryItem
{
@ -1111,6 +1113,8 @@ parent:
async AddMemoryReport(MemoryReport aReport);
async FinishMemoryReport(uint32_t aGeneration);
async AllocPipelineId() returns (PipelineId pipelineId);
both:
async AsyncMessage(nsString aMessage, CpowEntry[] aCpows,
Principal aPrincipal, ClonedMessageData aData);

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

@ -2,7 +2,7 @@
random-if(!haveTestPlugin) != plugin-sanity.html about:blank
fails-if(!haveTestPlugin) == plugin-sanity.html div-sanity.html
fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,160000) == plugin-alpha-zindex.html div-alpha-zindex.html
fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,164000) fails-if(webrender) == plugin-alpha-opacity.html div-alpha-opacity.html
fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,164000) == plugin-alpha-opacity.html div-alpha-opacity.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == windowless-clipping-1.html windowless-clipping-1-ref.html # bug 631832
# fuzzy because of anti-aliasing in dashed border
fuzzy(16,256) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == border-padding-1.html border-padding-1-ref.html # bug 629430

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

@ -536,7 +536,7 @@ nsCSPParser::keywordSource()
// Special case handling for 'self' which is not stored internally as a keyword,
// but rather creates a nsCSPHostSrc using the selfURI
if (CSP_IsKeyword(mCurToken, CSP_SELF)) {
return CSP_CreateHostSrcFromURI(mSelfURI);
return CSP_CreateHostSrcFromSelfURI(mSelfURI);
}
if (CSP_IsKeyword(mCurToken, CSP_STRICT_DYNAMIC)) {

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

@ -267,20 +267,21 @@ CSP_ContentTypeToDirective(nsContentPolicyType aType)
}
nsCSPHostSrc*
CSP_CreateHostSrcFromURI(nsIURI* aURI)
CSP_CreateHostSrcFromSelfURI(nsIURI* aSelfURI)
{
// Create the host first
nsCString host;
aURI->GetAsciiHost(host);
aSelfURI->GetAsciiHost(host);
nsCSPHostSrc *hostsrc = new nsCSPHostSrc(NS_ConvertUTF8toUTF16(host));
hostsrc->setGeneratedFromSelfKeyword();
// Add the scheme.
nsCString scheme;
aURI->GetScheme(scheme);
aSelfURI->GetScheme(scheme);
hostsrc->setScheme(NS_ConvertUTF8toUTF16(scheme));
int32_t port;
aURI->GetPort(&port);
aSelfURI->GetPort(&port);
// Only add port if it's not default port.
if (port > 0) {
nsAutoString portStr;
@ -349,13 +350,17 @@ CSP_IsQuotelessKeyword(const nsAString& aKey)
* @param aUpgradeInsecure
* Whether the policy makes use of the directive
* 'upgrade-insecure-requests'.
* @param aFromSelfURI
* Whether a scheme was generated from the keyword 'self'
* which then allows schemeless sources to match ws and wss.
*/
bool
permitsScheme(const nsAString& aEnforcementScheme,
nsIURI* aUri,
bool aReportOnly,
bool aUpgradeInsecure)
bool aUpgradeInsecure,
bool aFromSelfURI)
{
nsAutoCString scheme;
nsresult rv = aUri->GetScheme(scheme);
@ -374,8 +379,20 @@ permitsScheme(const nsAString& aEnforcementScheme,
// allow scheme-less sources where the protected resource is http
// and the load is https, see:
// http://www.w3.org/TR/CSP2/#match-source-expression
if (aEnforcementScheme.EqualsASCII("http") &&
scheme.EqualsASCII("https")) {
if (aEnforcementScheme.EqualsASCII("http")) {
if (scheme.EqualsASCII("https")) {
return true;
}
if ((scheme.EqualsASCII("ws") || scheme.EqualsASCII("wss")) && aFromSelfURI) {
return true;
}
}
if (aEnforcementScheme.EqualsASCII("https")) {
if (scheme.EqualsLiteral("wss") && aFromSelfURI) {
return true;
}
}
if (aEnforcementScheme.EqualsASCII("ws") && scheme.EqualsASCII("wss")) {
return true;
}
@ -484,7 +501,7 @@ nsCSPSchemeSrc::permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirect
if (mInvalidated) {
return false;
}
return permitsScheme(mScheme, aUri, aReportOnly, aUpgradeInsecure);
return permitsScheme(mScheme, aUri, aReportOnly, aUpgradeInsecure, false);
}
bool
@ -504,6 +521,7 @@ nsCSPSchemeSrc::toString(nsAString& outStr) const
nsCSPHostSrc::nsCSPHostSrc(const nsAString& aHost)
: mHost(aHost)
, mGeneratedFromSelfKeyword(false)
{
ToLowerCase(mHost);
}
@ -612,7 +630,7 @@ nsCSPHostSrc::permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected
// http://www.w3.org/TR/CSP11/#match-source-expression
// 4.3) scheme matching: Check if the scheme matches.
if (!permitsScheme(mScheme, aUri, aReportOnly, aUpgradeInsecure)) {
if (!permitsScheme(mScheme, aUri, aReportOnly, aUpgradeInsecure, mGeneratedFromSelfKeyword)) {
return false;
}

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

@ -186,7 +186,7 @@ nsresult CSP_AppendCSPFromHeader(nsIContentSecurityPolicy* aCsp,
class nsCSPHostSrc;
nsCSPHostSrc* CSP_CreateHostSrcFromURI(nsIURI* aURI);
nsCSPHostSrc* CSP_CreateHostSrcFromSelfURI(nsIURI* aSelfURI);
bool CSP_IsValidDirective(const nsAString& aDir);
bool CSP_IsDirective(const nsAString& aValue, CSPDirective aDir);
bool CSP_IsKeyword(const nsAString& aValue, enum CSPKeyword aKey);
@ -256,6 +256,9 @@ class nsCSPHostSrc : public nsCSPBaseSrc {
void setPort(const nsAString& aPort);
void appendPath(const nsAString &aPath);
inline void setGeneratedFromSelfKeyword() const
{ mGeneratedFromSelfKeyword = true;}
inline void getScheme(nsAString& outStr) const
{ outStr.Assign(mScheme); };
@ -273,6 +276,7 @@ class nsCSPHostSrc : public nsCSPBaseSrc {
nsString mHost;
nsString mPort;
nsString mPath;
mutable bool mGeneratedFromSelfKeyword;
};
/* =============== nsCSPKeywordSrc ============ */

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

@ -743,7 +743,7 @@ function* runTest() {
is(res.responseHeaders[header], test.responseHeaders[header],
"|xhr.getResponseHeader()|wrong response header (" + header + ") in test for " +
test.toSource());
is(res.allResponseHeaders[header], test.responseHeaders[header],
is(res.allResponseHeaders[header.toLowerCase()], test.responseHeaders[header],
"|xhr.getAllResponseHeaderss()|wrong response header (" + header + ") in test for " +
test.toSource());
}

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

@ -0,0 +1,31 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Bug 1345615: Allow websocket schemes when using 'self' in CSP</title>
<meta http-equiv="Content-Security-Policy" content="connect-src ws:">
</head>
<body>
<script type="application/javascript">
/* load socket using ws */
var wsSocket = new WebSocket("ws://example.com/tests/dom/security/test/csp/file_websocket_self");
wsSocket.onopen = function(e) {
window.parent.postMessage({result: "explicit-ws-loaded"}, "*");
wsSocket.close();
};
wsSocket.onerror = function(e) {
window.parent.postMessage({result: "explicit-ws-blocked"}, "*");
};
/* load socket using wss */
var wssSocket = new WebSocket("wss://example.com/tests/dom/security/test/csp/file_websocket_self");
wssSocket.onopen = function(e) {
window.parent.postMessage({result: "explicit-wss-loaded"}, "*");
wssSocket.close();
};
wssSocket.onerror = function(e) {
window.parent.postMessage({result: "explicit-wss-blocked"}, "*");
};
</script>
</body>
</html>

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

@ -0,0 +1,31 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Bug 1345615: Allow websocket schemes when using 'self' in CSP</title>
<meta http-equiv="Content-Security-Policy" content="connect-src 'self'">
</head>
<body>
<script type="application/javascript">
/* load socket using ws */
var wsSocket = new WebSocket("ws://example.com/tests/dom/security/test/csp/file_websocket_self");
wsSocket.onopen = function(e) {
window.parent.postMessage({result: "self-ws-loaded"}, "*");
wsSocket.close();
};
wsSocket.onerror = function(e) {
window.parent.postMessage({result: "self-ws-blocked"}, "*");
};
/* load socket using wss */
var wssSocket = new WebSocket("wss://example.com/tests/dom/security/test/csp/file_websocket_self");
wssSocket.onopen = function(e) {
window.parent.postMessage({result: "self-wss-loaded"}, "*");
wssSocket.close();
};
wssSocket.onerror = function(e) {
window.parent.postMessage({result: "self-wss-blocked"}, "*");
};
</script>
</body>
</html>

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

@ -0,0 +1,7 @@
from mod_pywebsocket import msgutil
def web_socket_do_extra_handshake(request):
pass
def web_socket_transfer_data(request):
pass

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

@ -208,6 +208,9 @@ support-files =
file_iframe_srcdoc.sjs
file_iframe_sandbox_srcdoc.html
file_iframe_sandbox_srcdoc.html^headers^
file_websocket_self.html
file_websocket_explicit.html
file_websocket_self_wsh.py
[test_base-uri.html]
[test_blob_data_schemes.html]
@ -298,3 +301,5 @@ tags = mcb
[test_punycode_host_src.html]
[test_iframe_sandbox_srcdoc.html]
[test_iframe_srcdoc.html]
[test_websocket_self.html]
skip-if = toolkit == 'android'

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

@ -0,0 +1,61 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Bug 1345615: Allow websocket schemes when using 'self' in CSP</title>
<!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<iframe style="width:100%;" id="test_ws_self_frame"></iframe>
<iframe style="width:100%;" id="test_ws_explicit_frame"></iframe>
<script class="testbody" type="text/javascript">
/* Description of the test:
* We load an iframe using connect-src 'self' and one
* iframe using connect-src ws: and make
* sure that in both cases ws: as well as wss: is allowed to load.
*/
SimpleTest.waitForExplicitFinish();
function finishTest() {
window.removeEventListener("message", receiveMessage);
SimpleTest.finish();
}
const TOTAL_TESTS = 4;
var counter = 0;
function checkResults(result) {
counter++;
if (result === "self-ws-loaded" || result === "self-wss-loaded" ||
result === "explicit-ws-loaded" || result === "explicit-wss-loaded") {
ok(true, "Evaluating: " + result);
}
else {
ok(false, "Evaluating: " + result);
}
if (counter < TOTAL_TESTS) {
return;
}
finishTest();
}
window.addEventListener("message", receiveMessage);
function receiveMessage(event) {
checkResults(event.data.result);
}
const HOST = "http://example.com/tests/dom/security/test/csp/";
var test_ws_self_frame = document.getElementById("test_ws_self_frame");
test_ws_self_frame.src = HOST + "file_websocket_self.html";
var test_ws_explicit_frame = document.getElementById("test_ws_explicit_frame");
test_ws_explicit_frame.src = HOST + "file_websocket_explicit.html";
</script>
</body>
</html>

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

@ -403,11 +403,15 @@ nsXBLProtoImplField::InstallField(JS::Handle<JSObject*> aBoundNode,
// We are going to run script via EvaluateString, so we need a script entry
// point, but as this is XBL related it does not appear in the HTML spec.
AutoEntryScript aes(globalObject, "XBL <field> initialization", true);
JSContext* cx = aes.cx();
NS_ASSERTION(!::JS_IsExceptionPending(cx),
"Shouldn't get here when an exception is pending!");
// We need an actual JSContext to do GetScopeForXBLExecution, and it needs to
// be in the compartment of globalObject. But we want our XBL execution scope
// to be our entry global.
AutoJSAPI jsapi;
if (!jsapi.Init(globalObject)) {
return NS_ERROR_UNEXPECTED;
}
MOZ_ASSERT(!::JS_IsExceptionPending(jsapi.cx()),
"Shouldn't get here when an exception is pending!");
JSAddonId* addonId = MapURIToAddonID(aBindingDocURI);
@ -419,9 +423,12 @@ nsXBLProtoImplField::InstallField(JS::Handle<JSObject*> aBoundNode,
// First, enter the xbl scope, build the element's scope chain, and use
// that as the scope chain for the evaluation.
JS::Rooted<JSObject*> scopeObject(cx, xpc::GetScopeForXBLExecution(cx, aBoundNode, addonId));
JS::Rooted<JSObject*> scopeObject(jsapi.cx(),
xpc::GetScopeForXBLExecution(jsapi.cx(), aBoundNode, addonId));
NS_ENSURE_TRUE(scopeObject, NS_ERROR_OUT_OF_MEMORY);
JSAutoCompartment ac(cx, scopeObject);
AutoEntryScript aes(scopeObject, "XBL <field> initialization", true);
JSContext* cx = aes.cx();
JS::Rooted<JS::Value> result(cx);
JS::CompileOptions options(cx);
@ -446,7 +453,8 @@ nsXBLProtoImplField::InstallField(JS::Handle<JSObject*> aBoundNode,
if (rv == NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW) {
// Report the exception now, before we try using the JSContext for
// the JS_DefineUCProperty call.
// the JS_DefineUCProperty call. Note that this reports in our current
// compartment, which is the XBL scope.
aes.ReportException();
}

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

@ -285,15 +285,24 @@ nsXBLProtoImplAnonymousMethod::Execute(nsIContent* aBoundElement, JSAddonId* aAd
// We are going to run script via JS::Call, so we need a script entry point,
// but as this is XBL related it does not appear in the HTML spec.
dom::AutoEntryScript aes(global, "XBL <constructor>/<destructor> invocation");
JSContext* cx = aes.cx();
// We need an actual JSContext to do GetScopeForXBLExecution, and it needs to
// be in the compartment of globalObject. But we want our XBL execution scope
// to be our entry global.
AutoJSAPI jsapi;
if (!jsapi.Init(global)) {
return NS_ERROR_UNEXPECTED;
}
JS::Rooted<JSObject*> globalObject(cx, global->GetGlobalJSObject());
JS::Rooted<JSObject*> globalObject(jsapi.cx(), global->GetGlobalJSObject());
JS::Rooted<JSObject*> scopeObject(cx, xpc::GetScopeForXBLExecution(cx, globalObject, aAddonId));
JS::Rooted<JSObject*> scopeObject(jsapi.cx(),
xpc::GetScopeForXBLExecution(jsapi.cx(), globalObject, aAddonId));
NS_ENSURE_TRUE(scopeObject, NS_ERROR_OUT_OF_MEMORY);
JSAutoCompartment ac(cx, scopeObject);
dom::AutoEntryScript aes(scopeObject,
"XBL <constructor>/<destructor> invocation",
true);
JSContext* cx = aes.cx();
JS::AutoObjectVector scopeChain(cx);
if (!nsJSUtils::GetScopeChainForElement(cx, aBoundElement->AsElement(),
scopeChain)) {

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

@ -39,3 +39,4 @@ support-files =
[test_bug872273.xhtml]
[test_bug1086996.xhtml]
[test_bug1098628_throw_from_construct.xhtml]
[test_bug1359859.xhtml]

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

@ -11,7 +11,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1098628
/** Test for Bug 1098628 **/
SimpleTest.waitForExplicitFinish();
SimpleTest.expectUncaughtException();
SimpleTest.monitorConsole(SimpleTest.finish, [{errorMessage: new RegExp('flimfniffle')}]);
addLoadEvent(function() {
SimpleTest.executeSoon(SimpleTest.endMonitorConsole);

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

@ -0,0 +1,41 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1359859
-->
<head>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<bindings xmlns="http://www.mozilla.org/xbl">
<binding id="testBinding">
<implementation>
<constructor>
XPCNativeWrapper.unwrap(window).running();
this.constructed = true;
throw new Error("Constructor threw");
</constructor>
<field name="throwingField">throw new Error("field threw")</field>
<field name="normalField">"hello"</field>
</implementation>
</binding>
</bindings>
<script>
// We need to wait for the binding to load.
SimpleTest.waitForExplicitFinish();
function running() {
// Wait for the rest of the constructor to run
SimpleTest.executeSoon(function() {
is(document.getElementById("bound").throwingField, undefined,
"Should not have a value for a throwing field");
is(document.getElementById("bound").normalField, "hello",
"Binding should be installed");
// The real test is that we haven't gotten any error events so far.
SimpleTest.finish();
});
}
</script>
</head>
<body>
<div id="bound" style="-moz-binding: url(#testBinding)"/>
</body>
</html>

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

@ -7,12 +7,46 @@
#include FT_TRUETYPE_TABLES_H
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
namespace mozilla {
namespace gfx {
bool
UnscaledFontFreeType::GetFontFileData(FontFileDataOutput aDataCallback, void* aBaton)
{
if (!mFile.empty()) {
int fd = open(mFile.c_str(), O_RDONLY);
if (fd < 0) {
return false;
}
struct stat buf;
if (fstat(fd, &buf) < 0 ||
// Don't erroneously read directories as files.
!S_ISREG(buf.st_mode) ||
// Verify the file size fits in a uint32_t.
buf.st_size <= 0 ||
off_t(uint32_t(buf.st_size)) != buf.st_size) {
close(fd);
return false;
}
uint32_t length = buf.st_size;
uint8_t* fontData =
reinterpret_cast<uint8_t*>(
mmap(nullptr, length, PROT_READ, MAP_PRIVATE, fd, 0));
close(fd);
if (fontData == MAP_FAILED) {
return false;
}
aDataCallback(fontData, length, mIndex, aBaton);
munmap(fontData, length);
return true;
}
bool success = false;
FT_ULong length = 0;
// Request the SFNT file. This may not always succeed for all font types.

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

@ -79,4 +79,4 @@ to make sure that mozjs_sys also has its Cargo.lock file updated if needed, henc
the need to run the cargo update command in js/src as well. Hopefully this will
be resolved soon.
Latest Commit: 3dd68f54e12bd5abf8ef41de4d4ec851620f7e4e
Latest Commit: 1437cc124696ecc95b726dffa17f918bb6ea5af1

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

@ -295,6 +295,14 @@ struct ParamTraits<mozilla::layers::DiagnosticTypes>
mozilla::layers::DiagnosticTypes::ALL_BITS>
{};
template <>
struct ParamTraits<mozilla::layers::ScrollDirection>
: public ContiguousEnumSerializer<
mozilla::layers::ScrollDirection,
mozilla::layers::ScrollDirection::NONE,
mozilla::layers::ScrollDirection::SENTINEL>
{};
/*
template <>
struct ParamTraits<mozilla::PixelFormat>

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

@ -12,6 +12,7 @@
#include "mozilla/layers/CompositorThread.h" // for CompositorThreadHolder
#include "mozilla/layers/LayerAnimationUtils.h" // for TimingFunctionToComputedTimingFunction
#include "mozilla/StyleAnimationValue.h" // for StyleAnimationValue, etc
#include "nsDisplayList.h" // for nsDisplayTransform, etc
namespace mozilla {
namespace layers {
@ -28,7 +29,15 @@ CompositorAnimationStorage::Clear()
mAnimatedValues.Clear();
mAnimations.Clear();
}
void
CompositorAnimationStorage::ClearById(const uint64_t& aId)
{
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
mAnimatedValues.Remove(aId);
mAnimations.Remove(aId);
}
AnimatedValue*
@ -131,7 +140,7 @@ SampleValue(float aPortion, const layers::Animation& aAnimation,
}
bool
AnimationHelper::SampleAnimationForEachNode(TimeStamp aPoint,
AnimationHelper::SampleAnimationForEachNode(TimeStamp aTime,
AnimationArray& aAnimations,
InfallibleTArray<AnimData>& aAnimationData,
StyleAnimationValue& aAnimationValue,
@ -157,7 +166,7 @@ AnimationHelper::SampleAnimationForEachNode(TimeStamp aPoint,
// finished, then use the hold time to stay at the same position.
TimeDuration elapsedDuration = animation.isNotPlaying()
? animation.holdTime()
: (aPoint - animation.startTime())
: (aTime - animation.startTime())
.MultDouble(animation.playbackRate());
TimingParams timing;
timing.mDuration.emplace(animation.duration());
@ -478,5 +487,85 @@ AnimationHelper::GetNextCompositorAnimationsId()
return nextId;
}
void
AnimationHelper::SampleAnimations(CompositorAnimationStorage* aStorage,
TimeStamp aTime)
{
MOZ_ASSERT(aStorage);
// Do nothing if there are no compositor animations
if (!aStorage->AnimationsCount()) {
return;
}
//Sample the animations in CompositorAnimationStorage
for (auto iter = aStorage->ConstAnimationsTableIter();
!iter.Done(); iter.Next()) {
bool hasInEffectAnimations = false;
AnimationArray* animations = iter.UserData();
StyleAnimationValue animationValue;
InfallibleTArray<AnimData> animationData;
AnimationHelper::SetAnimations(*animations,
animationData,
animationValue);
AnimationHelper::SampleAnimationForEachNode(aTime,
*animations,
animationData,
animationValue,
hasInEffectAnimations);
if (!hasInEffectAnimations) {
continue;
}
// Store the AnimatedValue
Animation& animation = animations->LastElement();
switch (animation.property()) {
case eCSSProperty_opacity: {
aStorage->SetAnimatedValue(iter.Key(),
animationValue.GetFloatValue());
break;
}
case eCSSProperty_transform: {
nsCSSValueSharedList* list = animationValue.GetCSSValueSharedListValue();
const TransformData& transformData = animation.data().get_TransformData();
nsPoint origin = transformData.origin();
// we expect all our transform data to arrive in device pixels
gfx::Point3D transformOrigin = transformData.transformOrigin();
nsDisplayTransform::FrameTransformProperties props(list,
transformOrigin);
gfx::Matrix4x4 transform =
nsDisplayTransform::GetResultingTransformMatrix(props, origin,
transformData.appUnitsPerDevPixel(),
0, &transformData.bounds());
gfx::Matrix4x4 frameTransform = transform;
//TODO how do we support this without layer information
// If our parent layer is a perspective layer, then the offset into reference
// frame coordinates is already on that layer. If not, then we need to ask
// for it to be added here.
// if (!aLayer->GetParent() ||
// !aLayer->GetParent()->GetTransformIsPerspective()) {
// nsLayoutUtils::PostTranslate(transform, origin,
// transformData.appUnitsPerDevPixel(),
// true);
// }
// if (ContainerLayer* c = aLayer->AsContainerLayer()) {
// transform.PostScale(c->GetInheritedXScale(), c->GetInheritedYScale(), 1);
// }
aStorage->SetAnimatedValue(iter.Key(),
Move(transform), Move(frameTransform),
transformData);
break;
}
default:
MOZ_ASSERT_UNREACHABLE("Unhandled animated property");
}
}
}
} // namespace layers
} // namespace mozilla

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

@ -101,6 +101,19 @@ public:
*/
AnimatedValue* GetAnimatedValue(const uint64_t& aId) const;
/**
* Return the iterator of animated value table
*/
AnimatedValueTable::Iterator ConstAnimatedValueTableIter() const
{
return mAnimatedValues.ConstIter();
}
uint32_t AnimatedValueCount() const
{
return mAnimatedValues.Count();
}
/**
* Set the animations based on the unique id
*/
@ -111,11 +124,25 @@ public:
*/
AnimationArray* GetAnimations(const uint64_t& aId) const;
/**
* Return the iterator of animations table
*/
AnimationsTable::Iterator ConstAnimationsTableIter() const
{
return mAnimations.ConstIter();
}
uint32_t AnimationsCount() const
{
return mAnimations.Count();
}
/**
* Clear AnimatedValues and Animations data
*/
void Clear();
void ClearById(const uint64_t& aId);
private:
~CompositorAnimationStorage() { Clear(); };
@ -127,18 +154,53 @@ private:
class AnimationHelper
{
public:
/*
* TODO Bug 1356509 Once we decouple the compositor animations and layers
* in parent side, the API will be called inside SampleAnimations.
* Before this, we expose this API for AsyncCompositionManager.
*
* Sample animations based on a given time stamp for a element(layer) with
* its animation data.
* Returns true if there exists compositor animation, and stores corresponding
* animated value in |aAnimationValue|.
*/
static bool
SampleAnimationForEachNode(TimeStamp aPoint,
SampleAnimationForEachNode(TimeStamp aTime,
AnimationArray& aAnimations,
InfallibleTArray<AnimData>& aAnimationData,
StyleAnimationValue& aAnimationValue,
bool& aHasInEffectAnimations);
/*
* TODO Bug 1356509 Once we decouple the compositor animations and layers
* in parent side, the API will be called inside SampleAnimations.
* Before this, we expose this API for AsyncCompositionManager.
*
* Populates AnimData stuctures into |aAnimData| based on |aAnimations|
*/
static void
SetAnimations(AnimationArray& aAnimations,
InfallibleTArray<AnimData>& aAnimData,
StyleAnimationValue& aBaseAnimationStyle);
/*
* Get a unique id to represent the compositor animation between child
* and parent side. This id will be used as a key to store animation
* data in the CompositorAnimationStorage per compositor.
* Each layer on the content side calls this when it gets new animation
* data.
*/
static uint64_t GetNextCompositorAnimationsId();
/*
* Sample animation based a given time stamp |aTime| and the animation
* data inside CompositorAnimationStorage |aStorage|. The animated values
* after sampling will be stored in CompositorAnimationStorage as well.
*/
static void
SampleAnimations(CompositorAnimationStorage* aStorage,
TimeStamp aTime);
};
} // namespace layers

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

@ -354,6 +354,18 @@ public:
return nullptr;
}
Maybe<uint64_t> GetReferentId() const
{
MOZ_ASSERT(IsValid());
if (AtBottomLayer()) {
return mLayer->AsRefLayer()
? Some(mLayer->AsRefLayer()->GetReferentId())
: Nothing();
}
return Nothing();
}
Maybe<ParentLayerIntRect> GetClipRect() const
{
MOZ_ASSERT(IsValid());

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

@ -695,6 +695,17 @@ Layer::GetLocalTransformTyped()
return ViewAs<LayerToParentLayerMatrix4x4>(GetLocalTransform());
}
bool
Layer::HasOpacityAnimation() const
{
for (uint32_t i = 0; i < mAnimations.Length(); i++) {
if (mAnimations[i].property() == eCSSProperty_opacity) {
return true;
}
}
return false;
}
bool
Layer::HasTransformAnimation() const
{

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

@ -1441,6 +1441,7 @@ public:
void SetAnimationGeneration(uint64_t aCount) { mAnimationGeneration = aCount; }
bool HasTransformAnimation() const;
bool HasOpacityAnimation() const;
StyleAnimationValue GetBaseAnimationStyle() const
{

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

@ -302,7 +302,8 @@ private:
enum class ScrollDirection : uint32_t {
NONE,
VERTICAL,
HORIZONTAL
HORIZONTAL,
SENTINEL /* for IPC serialization */
};
} // namespace layers

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

@ -0,0 +1,84 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GFX_UPDATEIMAGEHELPER_H
#define GFX_UPDATEIMAGEHELPER_H
#include "Layers.h"
#include "mozilla/layers/ImageClient.h"
#include "mozilla/layers/TextureClient.h"
#include "mozilla/layers/TextureClientRecycleAllocator.h"
#include "mozilla/layers/TextureWrapperImage.h"
#include "mozilla/gfx/Types.h"
namespace mozilla {
namespace layers {
class UpdateImageHelper
{
public:
UpdateImageHelper(ImageContainer* aImageContainer, ImageClient* aImageClient, gfx::IntSize aImageSize) :
mImageContainer(aImageContainer),
mImageClient(aImageClient),
mImageSize(aImageSize),
mIsLocked(false)
{
mTexture = mImageClient->GetTextureClientRecycler()->CreateOrRecycle(gfx::SurfaceFormat::B8G8R8A8,
mImageSize,
BackendSelector::Content,
TextureFlags::DEFAULT);
if (!mTexture) {
return;
}
mIsLocked = mTexture->Lock(OpenMode::OPEN_WRITE_ONLY);
if (!mIsLocked) {
return;
}
}
~UpdateImageHelper()
{
if (mIsLocked) {
mTexture->Unlock();
mIsLocked = false;
}
}
already_AddRefed<gfx::DrawTarget> GetDrawTarget()
{
RefPtr<gfx::DrawTarget> target = mTexture->BorrowDrawTarget();
return target.forget();
}
bool UpdateImage()
{
if (!mTexture) {
return false;
}
if (mIsLocked) {
mTexture->Unlock();
mIsLocked = false;
}
RefPtr<TextureWrapperImage> image = new TextureWrapperImage(mTexture,
gfx::IntRect(gfx::IntPoint(0, 0), mImageSize));
mImageContainer->SetCurrentImageInTransaction(image);
return mImageClient->UpdateImage(mImageContainer, /* unused */0);
}
private:
RefPtr<ImageContainer> mImageContainer;
RefPtr<ImageClient> mImageClient;
gfx::IntSize mImageSize;
RefPtr<TextureClient> mTexture;
bool mIsLocked;
};
} // namespace layers
} // namespace mozilla
#endif // GFX_UPDATEIMAGEHELPER_H

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

@ -22,6 +22,7 @@
#include "mozilla/layers/AsyncDragMetrics.h" // for AsyncDragMetrics
#include "mozilla/layers/CompositorBridgeParent.h" // for CompositorBridgeParent, etc
#include "mozilla/layers/LayerMetricsWrapper.h"
#include "mozilla/layers/WebRenderScrollDataWrapper.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/mozalloc.h" // for operator new
#include "mozilla/TouchEvents.h"
@ -216,12 +217,12 @@ APZCTreeManager::SetAllowedTouchBehavior(uint64_t aInputBlockId,
mInputQueue->SetAllowedTouchBehavior(aInputBlockId, aValues);
}
void
APZCTreeManager::UpdateHitTestingTree(uint64_t aRootLayerTreeId,
Layer* aRoot,
bool aIsFirstPaint,
uint64_t aOriginatingLayersId,
uint32_t aPaintSequenceNumber)
template<class ScrollNode> void // ScrollNode is a LayerMetricsWrapper or a WebRenderScrollDataWrapper
APZCTreeManager::UpdateHitTestingTreeImpl(uint64_t aRootLayerTreeId,
const ScrollNode& aRoot,
bool aIsFirstPaint,
uint64_t aOriginatingLayersId,
uint32_t aPaintSequenceNumber)
{
APZThreadUtils::AssertOnCompositorThread();
@ -271,11 +272,10 @@ APZCTreeManager::UpdateHitTestingTree(uint64_t aRootLayerTreeId,
ancestorTransforms.push(Matrix4x4());
mApzcTreeLog << "[start]\n";
LayerMetricsWrapper root(aRoot);
mTreeLock.AssertCurrentThreadOwns();
ForEachNode<ReverseIterator>(root,
[&](LayerMetricsWrapper aLayerMetrics)
ForEachNode<ReverseIterator>(aRoot,
[&](ScrollNode aLayerMetrics)
{
mApzcTreeLog << aLayerMetrics.Name() << '\t';
@ -308,10 +308,10 @@ APZCTreeManager::UpdateHitTestingTree(uint64_t aRootLayerTreeId,
MOZ_ASSERT(!node->GetFirstChild());
parent = node;
next = nullptr;
layersId = (aLayerMetrics.AsRefLayer() ? aLayerMetrics.AsRefLayer()->GetReferentId() : layersId);
layersId = aLayerMetrics.GetReferentId().valueOr(layersId);
indents.push(gfx::TreeAutoIndent(mApzcTreeLog));
},
[&](LayerMetricsWrapper aLayerMetrics)
[&](ScrollNode aLayerMetrics)
{
next = parent;
parent = parent->GetParent();
@ -340,11 +340,35 @@ APZCTreeManager::UpdateHitTestingTree(uint64_t aRootLayerTreeId,
#endif
}
void
APZCTreeManager::UpdateHitTestingTree(uint64_t aRootLayerTreeId,
Layer* aRoot,
bool aIsFirstPaint,
uint64_t aOriginatingLayersId,
uint32_t aPaintSequenceNumber)
{
LayerMetricsWrapper root(aRoot);
UpdateHitTestingTreeImpl(aRootLayerTreeId, root, aIsFirstPaint,
aOriginatingLayersId, aPaintSequenceNumber);
}
void
APZCTreeManager::UpdateHitTestingTree(uint64_t aRootLayerTreeId,
const WebRenderScrollData& aScrollData,
bool aIsFirstPaint,
uint64_t aOriginatingLayersId,
uint32_t aPaintSequenceNumber)
{
WebRenderScrollDataWrapper wrapper(&aScrollData);
UpdateHitTestingTreeImpl(aRootLayerTreeId, wrapper, aIsFirstPaint,
aOriginatingLayersId, aPaintSequenceNumber);
}
// Compute the clip region to be used for a layer with an APZC. This function
// is only called for layers which actually have scrollable metrics and an APZC.
static ParentLayerIntRegion
template<class ScrollNode> static ParentLayerIntRegion
ComputeClipRegion(GeckoContentController* aController,
const LayerMetricsWrapper& aLayer)
const ScrollNode& aLayer)
{
ParentLayerIntRegion clipRegion;
if (aLayer.GetClipRect()) {
@ -360,8 +384,8 @@ ComputeClipRegion(GeckoContentController* aController,
return clipRegion;
}
void
APZCTreeManager::PrintAPZCInfo(const LayerMetricsWrapper& aLayer,
template<class ScrollNode> void
APZCTreeManager::PrintAPZCInfo(const ScrollNode& aLayer,
const AsyncPanZoomController* apzc)
{
const FrameMetrics& metrics = aLayer.Metrics();
@ -389,8 +413,8 @@ APZCTreeManager::AttachNodeToTree(HitTestingTreeNode* aNode,
}
}
static EventRegions
GetEventRegions(const LayerMetricsWrapper& aLayer)
template<class ScrollNode> static EventRegions
GetEventRegions(const ScrollNode& aLayer)
{
if (aLayer.IsScrollInfoLayer()) {
ParentLayerIntRect compositionBounds(RoundedToInt(aLayer.Metrics().GetCompositionBounds()));
@ -422,9 +446,9 @@ APZCTreeManager::RecycleOrCreateNode(TreeBuildingState& aState,
return node.forget();
}
static EventRegionsOverride
template<class ScrollNode> static EventRegionsOverride
GetEventRegionsOverride(HitTestingTreeNode* aParent,
const LayerMetricsWrapper& aLayer)
const ScrollNode& aLayer)
{
// Make it so that if the flag is set on the layer tree, it automatically
// propagates to all the nodes in the corresponding subtree rooted at that
@ -460,8 +484,8 @@ APZCTreeManager::NotifyScrollbarDragRejected(const ScrollableLayerGuid& aGuid) c
state->mController->NotifyAsyncScrollbarDragRejected(aGuid.mScrollId);
}
HitTestingTreeNode*
APZCTreeManager::PrepareNodeForLayer(const LayerMetricsWrapper& aLayer,
template<class ScrollNode> HitTestingTreeNode*
APZCTreeManager::PrepareNodeForLayer(const ScrollNode& aLayer,
const FrameMetrics& aMetrics,
uint64_t aLayersId,
const gfx::Matrix4x4& aAncestorTransform,

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

@ -40,6 +40,7 @@ class LayerMetricsWrapper;
class InputQueue;
class GeckoContentController;
class HitTestingTreeNode;
class WebRenderScrollData;
/**
* ****************** NOTE ON LOCK ORDERING IN APZ **************************
@ -131,6 +132,18 @@ public:
uint64_t aOriginatingLayersId,
uint32_t aPaintSequenceNumber);
/**
* Same as the above UpdateHitTestingTree, except slightly modified to take
* the scrolling data passed over PWebRenderBridge instead of the raw layer
* tree. This version is used when WebRender is enabled because we don't have
* shadow layers in that scenario.
*/
void UpdateHitTestingTree(uint64_t aRootLayerTreeId,
const WebRenderScrollData& aScrollData,
bool aIsFirstPaint,
uint64_t aOriginatingLayersId,
uint32_t aPaintSequenceNumber);
/**
* Walk the tree of APZCs and flushes the repaint requests for all the APZCS
* corresponding to the given layers id. Finally, sends a flush complete
@ -440,6 +453,13 @@ private:
typedef bool (*GuidComparator)(const ScrollableLayerGuid&, const ScrollableLayerGuid&);
/* Helpers */
template<class ScrollNode>
void UpdateHitTestingTreeImpl(uint64_t aRootLayerTreeId,
const ScrollNode& aRoot,
bool aIsFirstPaint,
uint64_t aOriginatingLayersId,
uint32_t aPaintSequenceNumber);
void AttachNodeToTree(HitTestingTreeNode* aNode,
HitTestingTreeNode* aParent,
HitTestingTreeNode* aNextSibling);
@ -470,7 +490,8 @@ private:
already_AddRefed<HitTestingTreeNode> RecycleOrCreateNode(TreeBuildingState& aState,
AsyncPanZoomController* aApzc,
uint64_t aLayersId);
HitTestingTreeNode* PrepareNodeForLayer(const LayerMetricsWrapper& aLayer,
template<class ScrollNode>
HitTestingTreeNode* PrepareNodeForLayer(const ScrollNode& aLayer,
const FrameMetrics& aMetrics,
uint64_t aLayersId,
const gfx::Matrix4x4& aAncestorTransform,
@ -478,7 +499,8 @@ private:
HitTestingTreeNode* aNextSibling,
TreeBuildingState& aState);
void PrintAPZCInfo(const LayerMetricsWrapper& aLayer,
template<class ScrollNode>
void PrintAPZCInfo(const ScrollNode& aLayer,
const AsyncPanZoomController* apzc);
void NotifyScrollbarDragRejected(const ScrollableLayerGuid& aGuid) const;

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

@ -268,6 +268,9 @@ public:
case ScrollDirection::VERTICAL:
EXPECT_EQ(PANNING_LOCKED_Y, mState);
break;
case ScrollDirection::SENTINEL:
MOZ_ASSERT(false, "Invalid value");
break;
}
}

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

@ -70,6 +70,8 @@ public:
static already_AddRefed<TextureClient> CreateTextureClientForImage(Image* aImage, KnowsCompositor* aForwarder);
uint32_t GetLastUpdateGenerationCounter() { return mLastUpdateGenerationCounter; }
protected:
ImageClient(CompositableForwarder* aFwd, TextureFlags aFlags,
CompositableType aType);
@ -101,6 +103,8 @@ public:
ImageClientSingle* AsImageClientSingle() override { return this; }
bool IsEmpty() { return mBuffers.IsEmpty(); }
protected:
struct Buffer {
RefPtr<TextureClient> mTextureClient;

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

@ -892,11 +892,15 @@ TextureClient::InitIPDLActor(CompositableForwarder* aForwarder)
return false;
}
// Try external image id allocation.
mExternalImageId = aForwarder->GetTextureForwarder()->GetNextExternalImageId();
PTextureChild* actor = aForwarder->GetTextureForwarder()->CreateTexture(
desc,
aForwarder->GetCompositorBackendType(),
GetFlags(),
mSerial);
mSerial,
mExternalImageId);
if (!actor) {
gfxCriticalNote << static_cast<int32_t>(desc.type()) << ", "
<< static_cast<int32_t>(aForwarder->GetCompositorBackendType()) << ", "
@ -948,11 +952,15 @@ TextureClient::InitIPDLActor(KnowsCompositor* aForwarder)
return false;
}
// Try external image id allocation.
mExternalImageId = aForwarder->GetTextureForwarder()->GetNextExternalImageId();
PTextureChild* actor = fwd->CreateTexture(
desc,
aForwarder->GetCompositorBackendType(),
GetFlags(),
mSerial);
mSerial,
mExternalImageId);
if (!actor) {
gfxCriticalNote << static_cast<int32_t>(desc.type()) << ", "
<< static_cast<int32_t>(aForwarder->GetCompositorBackendType()) << ", "

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

@ -25,6 +25,7 @@
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
#include "mozilla/mozalloc.h" // for operator delete
#include "mozilla/gfx/CriticalSection.h"
#include "mozilla/webrender/WebRenderTypes.h"
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsISupportsImpl.h" // for TextureImage::AddRef, etc
#include "GfxTexturesReporter.h"
@ -746,6 +747,13 @@ protected:
// Serial id of TextureClient. It is unique in current process.
const uint64_t mSerial;
// External image id. It is unique if it is allocated.
// The id is allocated in TextureClient::InitIPDLActor().
// Its allocation is supported by
// CompositorBridgeChild and ImageBridgeChild for now.
wr::MaybeExternalImageId mExternalImageId;
// Used to assign serial ids of TextureClient.
static mozilla::Atomic<uint64_t> sSerialCounter;

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

@ -648,7 +648,7 @@ ApplyAnimatedValue(Layer* aLayer,
static AnimationProcessTypes
SampleAnimations(Layer* aLayer,
CompositorAnimationStorage* aStorage,
TimeStamp aPoint,
TimeStamp aTime,
uint64_t* aLayerAreaAnimated)
{
// This tracks the first-encountered RefLayer in the layer tree. Since we are
@ -672,7 +672,7 @@ SampleAnimations(Layer* aLayer,
bool hasInEffectAnimations = false;
StyleAnimationValue animationValue = layer->GetBaseAnimationStyle();
if (AnimationHelper::SampleAnimationForEachNode(aPoint,
if (AnimationHelper::SampleAnimationForEachNode(aTime,
layer->GetAnimations(),
layer->GetAnimationData(),
animationValue,

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

@ -5,15 +5,14 @@
#include "ImageComposite.h"
// this is also defined in ImageHost.cpp
#define BIAS_TIME_MS 1.0
namespace mozilla {
using namespace gfx;
namespace layers {
/* static */ const float ImageComposite::BIAS_TIME_MS = 1.0f;
ImageComposite::ImageComposite()
: mLastFrameID(-1)
, mLastProducerID(-1)
@ -24,8 +23,8 @@ ImageComposite::~ImageComposite()
{
}
static TimeStamp
GetBiasedTime(const TimeStamp& aInput, ImageComposite::Bias aBias)
/* static */ TimeStamp
ImageComposite::GetBiasedTime(const TimeStamp& aInput, ImageComposite::Bias aBias)
{
switch (aBias) {
case ImageComposite::BIAS_NEGATIVE:
@ -120,5 +119,3 @@ ImageComposite::TimedImage* ImageComposite::ChooseImage()
} // namespace layers
} // namespace mozilla
#undef BIAS_TIME_MS

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

@ -20,6 +20,8 @@ namespace layers {
class ImageComposite
{
public:
static const float BIAS_TIME_MS;
explicit ImageComposite();
~ImageComposite();
@ -47,6 +49,8 @@ public:
BIAS_POSITIVE,
};
static TimeStamp GetBiasedTime(const TimeStamp& aInput, ImageComposite::Bias aBias);
protected:
static Bias UpdateBias(const TimeStamp& aCompositionTime,
const TimeStamp& aCompositedImageTime,

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

@ -16,9 +16,6 @@
#include "nsPrintfCString.h" // for nsPrintfCString
#include "nsString.h" // for nsAutoCString
// this is also defined in ImageComposite.cpp
#define BIAS_TIME_MS 1.0
namespace mozilla {
using namespace gfx;
@ -476,5 +473,3 @@ ImageHost::GenEffect(const gfx::SamplingFilter aSamplingFilter)
} // namespace layers
} // namespace mozilla
#undef BIAS_TIME_MS

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

@ -65,7 +65,7 @@ namespace layers {
class TextureParent : public ParentActor<PTextureParent>
{
public:
explicit TextureParent(HostIPCAllocator* aAllocator, uint64_t aSerial);
explicit TextureParent(HostIPCAllocator* aAllocator, uint64_t aSerial, const wr::MaybeExternalImageId& aExternalImageId);
~TextureParent();
@ -87,6 +87,7 @@ public:
RefPtr<TextureHost> mTextureHost;
// mSerial is unique in TextureClient's process.
const uint64_t mSerial;
wr::MaybeExternalImageId mExternalImageId;
};
static bool
@ -109,7 +110,8 @@ TextureHost::CreateIPDLActor(HostIPCAllocator* aAllocator,
const SurfaceDescriptor& aSharedData,
LayersBackend aLayersBackend,
TextureFlags aFlags,
uint64_t aSerial)
uint64_t aSerial,
const wr::MaybeExternalImageId& aExternalImageId)
{
if (aSharedData.type() == SurfaceDescriptor::TSurfaceDescriptorBuffer &&
aSharedData.get_SurfaceDescriptorBuffer().data().type() == MemoryOrShmem::Tuintptr_t &&
@ -118,7 +120,7 @@ TextureHost::CreateIPDLActor(HostIPCAllocator* aAllocator,
NS_ERROR("A client process is trying to peek at our address space using a MemoryTexture!");
return nullptr;
}
TextureParent* actor = new TextureParent(aAllocator, aSerial);
TextureParent* actor = new TextureParent(aAllocator, aSerial, aExternalImageId);
if (!actor->Init(aSharedData, aLayersBackend, aFlags)) {
delete actor;
return nullptr;
@ -196,7 +198,8 @@ already_AddRefed<TextureHost>
TextureHost::Create(const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
LayersBackend aBackend,
TextureFlags aFlags)
TextureFlags aFlags,
wr::MaybeExternalImageId& aExternalImageId)
{
RefPtr<TextureHost> result;
@ -243,7 +246,8 @@ TextureHost::Create(const SurfaceDescriptor& aDesc,
}
if (WrapWithWebRenderTextureHost(aDeallocator, aBackend, aFlags)) {
result = new WebRenderTextureHost(aDesc, aFlags, result);
MOZ_ASSERT(aExternalImageId.isSome());
result = new WebRenderTextureHost(aDesc, aFlags, result, aExternalImageId.ref());
}
return result.forget();
@ -1080,9 +1084,10 @@ size_t MemoryTextureHost::GetBufferSize()
return std::numeric_limits<size_t>::max();
}
TextureParent::TextureParent(HostIPCAllocator* aSurfaceAllocator, uint64_t aSerial)
TextureParent::TextureParent(HostIPCAllocator* aSurfaceAllocator, uint64_t aSerial, const wr::MaybeExternalImageId& aExternalImageId)
: mSurfaceAllocator(aSurfaceAllocator)
, mSerial(aSerial)
, mExternalImageId(aExternalImageId)
{
MOZ_COUNT_CTOR(TextureParent);
}
@ -1109,7 +1114,8 @@ TextureParent::Init(const SurfaceDescriptor& aSharedData,
mTextureHost = TextureHost::Create(aSharedData,
mSurfaceAllocator,
aBackend,
aFlags);
aFlags,
mExternalImageId);
if (mTextureHost) {
mTextureHost->mActor = this;
}

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

@ -21,6 +21,7 @@
#include "mozilla/layers/LayersSurfaces.h"
#include "mozilla/mozalloc.h" // for operator delete
#include "mozilla/UniquePtr.h" // for UniquePtr
#include "mozilla/webrender/WebRenderTypes.h"
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsDebug.h" // for NS_RUNTIMEABORT
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
@ -386,7 +387,8 @@ public:
const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
LayersBackend aBackend,
TextureFlags aFlags);
TextureFlags aFlags,
wr::MaybeExternalImageId& aExternalImageId);
/**
* Lock the texture host for compositing.
@ -519,7 +521,8 @@ public:
const SurfaceDescriptor& aSharedData,
LayersBackend aLayersBackend,
TextureFlags aFlags,
uint64_t aSerial);
uint64_t aSerial,
const wr::MaybeExternalImageId& aExternalImageId);
static bool DestroyIPDLActor(PTextureParent* actor);
/**

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

@ -885,7 +885,8 @@ CompositorBridgeChild::AllocPTextureChild(const SurfaceDescriptor&,
const LayersBackend&,
const TextureFlags&,
const uint64_t&,
const uint64_t& aSerial)
const uint64_t& aSerial,
const wr::MaybeExternalImageId& aExternalImageId)
{
return TextureClient::CreateIPDLActor();
}
@ -1055,9 +1056,10 @@ PTextureChild*
CompositorBridgeChild::CreateTexture(const SurfaceDescriptor& aSharedData,
LayersBackend aLayersBackend,
TextureFlags aFlags,
uint64_t aSerial)
uint64_t aSerial,
wr::MaybeExternalImageId& aExternalImageId)
{
return PCompositorBridgeChild::SendPTextureConstructor(aSharedData, aLayersBackend, aFlags, 0 /* FIXME? */, aSerial);
return PCompositorBridgeChild::SendPTextureConstructor(aSharedData, aLayersBackend, aFlags, 0 /* FIXME? */, aSerial, aExternalImageId);
}
bool
@ -1185,7 +1187,7 @@ CompositorBridgeChild::DeallocPWebRenderBridgeChild(PWebRenderBridgeChild* aActo
return true;
}
uint64_t
wr::MaybeExternalImageId
CompositorBridgeChild::GetNextExternalImageId()
{
static uint32_t sNextID = 1;
@ -1194,7 +1196,7 @@ CompositorBridgeChild::GetNextExternalImageId()
uint64_t imageId = mNamespace;
imageId = imageId << 32 | sNextID;
return imageId;
return Some(wr::ToExternalImageId(imageId));
}
} // namespace layers

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

@ -13,6 +13,7 @@
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/layers/PCompositorBridgeChild.h"
#include "mozilla/layers/TextureForwarder.h" // for TextureForwarder
#include "mozilla/webrender/WebRenderTypes.h"
#include "nsClassHashtable.h" // for nsClassHashtable
#include "nsCOMPtr.h" // for nsCOMPtr
#include "nsHashKeys.h" // for nsUint64HashKey
@ -122,7 +123,8 @@ public:
const LayersBackend& aLayersBackend,
const TextureFlags& aFlags,
const uint64_t& aId,
const uint64_t& aSerial) override;
const uint64_t& aSerial,
const wr::MaybeExternalImageId& aExternalImageId) override;
virtual bool DeallocPTextureChild(PTextureChild* actor) override;
@ -131,7 +133,8 @@ public:
virtual PTextureChild* CreateTexture(const SurfaceDescriptor& aSharedData,
LayersBackend aLayersBackend,
TextureFlags aFlags,
uint64_t aSerial) override;
uint64_t aSerial,
wr::MaybeExternalImageId& aExternalImageId) override;
virtual void HandleFatalError(const char* aName, const char* aMsg) const override;
@ -234,7 +237,7 @@ public:
return mDeviceResetSequenceNumber;
}
uint64_t GetNextExternalImageId();
wr::MaybeExternalImageId GetNextExternalImageId() override;
private:
// Private destructor, to discourage deletion outside of Release():

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

@ -1601,7 +1601,7 @@ CompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::PipelineId& aPipel
// child process invoking this codepath before it's ready
MOZ_RELEASE_ASSERT(false);
#endif
MOZ_ASSERT(aPipelineId.mHandle == mRootLayerTreeID);
MOZ_ASSERT(wr::AsUint64(aPipelineId) == mRootLayerTreeID);
MOZ_ASSERT(!mWrBridge);
MOZ_ASSERT(!mCompositor);
MOZ_ASSERT(!mCompositorScheduler);
@ -1621,9 +1621,8 @@ CompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::PipelineId& aPipel
MOZ_ASSERT(mCompositorScheduler);
mWrBridge.get()->AddRef(); // IPDL reference
MonitorAutoLock lock(*sIndirectLayerTreesLock);
auto pipelineHandle = aPipelineId.mHandle;
MOZ_ASSERT(sIndirectLayerTrees[pipelineHandle].mWrBridge == nullptr);
sIndirectLayerTrees[pipelineHandle].mWrBridge = mWrBridge;
MOZ_ASSERT(sIndirectLayerTrees[mRootLayerTreeID].mWrBridge == nullptr);
sIndirectLayerTrees[mRootLayerTreeID].mWrBridge = mWrBridge;
*aTextureFactoryIdentifier = mWrBridge->GetTextureFactoryIdentifier();
return mWrBridge;
}
@ -2112,9 +2111,10 @@ CompositorBridgeParent::AllocPTextureParent(const SurfaceDescriptor& aSharedData
const LayersBackend& aLayersBackend,
const TextureFlags& aFlags,
const uint64_t& aId,
const uint64_t& aSerial)
const uint64_t& aSerial,
const wr::MaybeExternalImageId& aExternalImageId)
{
return TextureHost::CreateIPDLActor(this, aSharedData, aLayersBackend, aFlags, aSerial);
return TextureHost::CreateIPDLActor(this, aSharedData, aLayersBackend, aFlags, aSerial, aExternalImageId);
}
bool

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

@ -250,7 +250,8 @@ public:
const LayersBackend& aLayersBackend,
const TextureFlags& aFlags,
const uint64_t& aId,
const uint64_t& aSerial) override;
const uint64_t& aSerial,
const wr::MaybeExternalImageId& aExternalImageId) override;
virtual bool DeallocPTextureParent(PTextureParent* actor) override;
virtual bool IsSameProcess() const override;

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

@ -189,17 +189,17 @@ CrossProcessCompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::Pipeli
// child process invoking this codepath before it's ready
MOZ_RELEASE_ASSERT(false);
#endif
uint64_t layersId = wr::AsUint64(aPipelineId);
// Check to see if this child process has access to this layer tree.
if (!LayerTreeOwnerTracker::Get()->IsMapped(aPipelineId.mHandle, OtherPid())) {
if (!LayerTreeOwnerTracker::Get()->IsMapped(layersId, OtherPid())) {
NS_ERROR("Unexpected layers id in AllocPAPZCTreeManagerParent; dropping message...");
return nullptr;
}
auto pipelineHandle = aPipelineId.mHandle;
MonitorAutoLock lock(*sIndirectLayerTreesLock);
MOZ_ASSERT(sIndirectLayerTrees.find(pipelineHandle) != sIndirectLayerTrees.end());
MOZ_ASSERT(sIndirectLayerTrees[pipelineHandle].mWrBridge == nullptr);
CompositorBridgeParent* cbp = sIndirectLayerTrees[pipelineHandle].mParent;
MOZ_ASSERT(sIndirectLayerTrees.find(layersId) != sIndirectLayerTrees.end());
MOZ_ASSERT(sIndirectLayerTrees[layersId].mWrBridge == nullptr);
CompositorBridgeParent* cbp = sIndirectLayerTrees[layersId].mParent;
WebRenderBridgeParent* root = sIndirectLayerTrees[cbp->RootLayerTreeId()].mWrBridge.get();
WebRenderBridgeParent* parent = nullptr;
@ -208,8 +208,8 @@ CrossProcessCompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::Pipeli
parent = new WebRenderBridgeParent(this, aPipelineId, nullptr, root->CompositorScheduler(), Move(api), Move(holder));
parent->AddRef(); // IPDL reference
sIndirectLayerTrees[pipelineHandle].mCrossProcessParent = this;
sIndirectLayerTrees[pipelineHandle].mWrBridge = parent;
sIndirectLayerTrees[layersId].mCrossProcessParent = this;
sIndirectLayerTrees[layersId].mWrBridge = parent;
*aTextureFactoryIdentifier = parent->GetTextureFactoryIdentifier();
*aIdNamespace = parent->GetIdNameSpace();
@ -225,7 +225,7 @@ CrossProcessCompositorBridgeParent::DeallocPWebRenderBridgeParent(PWebRenderBrid
MOZ_RELEASE_ASSERT(false);
#endif
WebRenderBridgeParent* parent = static_cast<WebRenderBridgeParent*>(aActor);
EraseLayerState(parent->PipelineId().mHandle);
EraseLayerState(wr::AsUint64(parent->PipelineId()));
parent->Release(); // IPDL reference
return true;
}
@ -509,7 +509,8 @@ CrossProcessCompositorBridgeParent::AllocPTextureParent(const SurfaceDescriptor&
const LayersBackend& aLayersBackend,
const TextureFlags& aFlags,
const uint64_t& aId,
const uint64_t& aSerial)
const uint64_t& aSerial,
const wr::MaybeExternalImageId& aExternalImageId)
{
CompositorBridgeParent::LayerTreeState* state = nullptr;
@ -532,7 +533,7 @@ CrossProcessCompositorBridgeParent::AllocPTextureParent(const SurfaceDescriptor&
gfxDevCrash(gfx::LogReason::PAllocTextureBackendMismatch) << "Texture backend is wrong";
}
return TextureHost::CreateIPDLActor(this, aSharedData, aLayersBackend, aFlags, aSerial);
return TextureHost::CreateIPDLActor(this, aSharedData, aLayersBackend, aFlags, aSerial, aExternalImageId);
}
bool

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

@ -130,7 +130,8 @@ public:
const LayersBackend& aLayersBackend,
const TextureFlags& aFlags,
const uint64_t& aId,
const uint64_t& aSerial) override;
const uint64_t& aSerial,
const wr::MaybeExternalImageId& aExternalImageId) override;
virtual bool DeallocPTextureParent(PTextureParent* actor) override;

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

@ -973,7 +973,8 @@ PTextureChild*
ImageBridgeChild::AllocPTextureChild(const SurfaceDescriptor&,
const LayersBackend&,
const TextureFlags&,
const uint64_t& aSerial)
const uint64_t& aSerial,
const wr::MaybeExternalImageId& aExternalImageId)
{
MOZ_ASSERT(CanSend());
return TextureClient::CreateIPDLActor();
@ -1044,10 +1045,11 @@ PTextureChild*
ImageBridgeChild::CreateTexture(const SurfaceDescriptor& aSharedData,
LayersBackend aLayersBackend,
TextureFlags aFlags,
uint64_t aSerial)
uint64_t aSerial,
wr::MaybeExternalImageId& aExternalImageId)
{
MOZ_ASSERT(CanSend());
return SendPTextureConstructor(aSharedData, aLayersBackend, aFlags, aSerial);
return SendPTextureConstructor(aSharedData, aLayersBackend, aFlags, aSerial, aExternalImageId);
}
static bool
@ -1156,7 +1158,7 @@ ImageBridgeChild::HandleFatalError(const char* aName, const char* aMsg) const
dom::ContentChild::FatalErrorIfNotUsingGPUProcess(aName, aMsg, OtherPid());
}
uint64_t
wr::MaybeExternalImageId
ImageBridgeChild::GetNextExternalImageId()
{
static uint32_t sNextID = 1;
@ -1165,7 +1167,7 @@ ImageBridgeChild::GetNextExternalImageId()
uint64_t imageId = mNamespace;
imageId = imageId << 32 | sNextID;
return imageId;
return Some(wr::ToExternalImageId(imageId));
}
} // namespace layers

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

@ -17,6 +17,7 @@
#include "mozilla/layers/CompositorTypes.h"
#include "mozilla/layers/PImageBridgeChild.h"
#include "mozilla/Mutex.h"
#include "mozilla/webrender/WebRenderTypes.h"
#include "nsDebug.h" // for NS_RUNTIMEABORT
#include "nsIObserver.h"
#include "nsRegion.h" // for nsIntRegion
@ -169,7 +170,11 @@ public:
virtual base::ProcessId GetParentPid() const override { return OtherPid(); }
virtual PTextureChild*
AllocPTextureChild(const SurfaceDescriptor& aSharedData, const LayersBackend& aLayersBackend, const TextureFlags& aFlags, const uint64_t& aSerial) override;
AllocPTextureChild(const SurfaceDescriptor& aSharedData,
const LayersBackend& aLayersBackend,
const TextureFlags& aFlags,
const uint64_t& aSerial,
const wr::MaybeExternalImageId& aExternalImageId) override;
virtual bool
DeallocPTextureChild(PTextureChild* actor) override;
@ -326,7 +331,8 @@ public:
virtual PTextureChild* CreateTexture(const SurfaceDescriptor& aSharedData,
LayersBackend aLayersBackend,
TextureFlags aFlags,
uint64_t aSerial) override;
uint64_t aSerial,
wr::MaybeExternalImageId& aExternalImageId) override;
virtual bool IsSameProcess() const override;
@ -339,7 +345,7 @@ public:
virtual void HandleFatalError(const char* aName, const char* aMsg) const override;
uint64_t GetNextExternalImageId();
virtual wr::MaybeExternalImageId GetNextExternalImageId() override;
protected:
explicit ImageBridgeChild(uint32_t aNamespace);

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

@ -245,9 +245,10 @@ PTextureParent*
ImageBridgeParent::AllocPTextureParent(const SurfaceDescriptor& aSharedData,
const LayersBackend& aLayersBackend,
const TextureFlags& aFlags,
const uint64_t& aSerial)
const uint64_t& aSerial,
const wr::MaybeExternalImageId& aExternalImageId)
{
return TextureHost::CreateIPDLActor(this, aSharedData, aLayersBackend, aFlags, aSerial);
return TextureHost::CreateIPDLActor(this, aSharedData, aLayersBackend, aFlags, aSerial, aExternalImageId);
}
bool

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

@ -77,7 +77,8 @@ public:
virtual PTextureParent* AllocPTextureParent(const SurfaceDescriptor& aSharedData,
const LayersBackend& aLayersBackend,
const TextureFlags& aFlags,
const uint64_t& aSerial) override;
const uint64_t& aSerial,
const wr::MaybeExternalImageId& aExternalImageId) override;
virtual bool DeallocPTextureParent(PTextureParent* actor) override;
virtual mozilla::ipc::IPCResult RecvNewCompositable(const CompositableHandle& aHandle,

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

@ -16,6 +16,7 @@ include protocol PLayerTransaction;
include protocol PTexture;
include protocol PWebRenderBridge;
include "mozilla/GfxMessageUtils.h";
include "mozilla/layers/WebRenderMessageUtils.h";
using struct mozilla::null_t from "ipc/IPCMessageUtils.h";
using struct mozilla::layers::TextureFactoryIdentifier from "mozilla/layers/CompositorTypes.h";
@ -37,6 +38,7 @@ using mozilla::layers::TextureFlags from "mozilla/layers/CompositorTypes.h";
using mozilla::layers::CompositorOptions from "mozilla/layers/CompositorOptions.h";
using mozilla::wr::PipelineId from "mozilla/webrender/WebRenderTypes.h";
using base::ProcessId from "base/process.h";
using mozilla::wr::MaybeExternalImageId from "mozilla/webrender/WebRenderTypes.h";
namespace mozilla {
namespace layers {
@ -245,7 +247,7 @@ parent:
*/
async AllPluginsCaptured();
async PTexture(SurfaceDescriptor aSharedData, LayersBackend aBackend, TextureFlags aTextureFlags, uint64_t id, uint64_t aSerial);
async PTexture(SurfaceDescriptor aSharedData, LayersBackend aBackend, TextureFlags aTextureFlags, uint64_t id, uint64_t aSerial, MaybeExternalImageId aExternalImageId);
sync SyncWithCompositor();

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

@ -10,10 +10,12 @@ include ProtocolTypes;
include protocol PMediaSystemResourceManager;
include "mozilla/GfxMessageUtils.h";
include "mozilla/layers/WebRenderMessageUtils.h";
using struct mozilla::layers::TextureInfo from "mozilla/layers/CompositorTypes.h";
using mozilla::layers::TextureFlags from "mozilla/layers/CompositorTypes.h";
using mozilla::layers::CompositableHandle from "mozilla/layers/LayersTypes.h";
using mozilla::wr::MaybeExternalImageId from "mozilla/webrender/WebRenderTypes.h";
using PlatformThreadId from "base/platform_thread.h";
@ -54,7 +56,7 @@ parent:
// before sending closing the channel.
sync WillClose();
async PTexture(SurfaceDescriptor aSharedData, LayersBackend aBackend, TextureFlags aTextureFlags, uint64_t aSerial);
async PTexture(SurfaceDescriptor aSharedData, LayersBackend aBackend, TextureFlags aTextureFlags, uint64_t aSerial, MaybeExternalImageId aExternalImageId);
async PMediaSystemResourceManager();
sync NewCompositable(CompositableHandle aHandle, TextureInfo aInfo);

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

@ -17,10 +17,12 @@ include protocol PTexture;
using struct mozilla::layers::TextureInfo from "mozilla/layers/CompositorTypes.h";
using mozilla::layers::CompositableHandle from "mozilla/layers/LayersTypes.h";
using mozilla::wr::ByteBuffer from "mozilla/webrender/WebRenderTypes.h";
using mozilla::wr::ExternalImageId from "mozilla/webrender/WebRenderTypes.h";
using mozilla::wr::ImageKey from "mozilla/webrender/WebRenderTypes.h";
using mozilla::wr::FontKey from "mozilla/webrender/WebRenderTypes.h";
using WrBuiltDisplayListDescriptor from "mozilla/webrender/webrender_ffi.h";
using WrAuxiliaryListsDescriptor from "mozilla/webrender/webrender_ffi.h";
using mozilla::layers::WebRenderScrollData from "mozilla/layers/WebRenderScrollData.h";
namespace mozilla {
namespace layers {
@ -50,13 +52,15 @@ parent:
async DeleteFont(FontKey aFontKey);
async DPBegin(IntSize aSize);
async DPEnd(IntSize aSize, WebRenderParentCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, uint64_t transactionId,
ByteBuffer aDL, WrBuiltDisplayListDescriptor aDLDesc, ByteBuffer aAux, WrAuxiliaryListsDescriptor aAuxDesc);
ByteBuffer aDL, WrBuiltDisplayListDescriptor aDLDesc, ByteBuffer aAux, WrAuxiliaryListsDescriptor aAuxDesc,
WebRenderScrollData aScrollData);
sync DPSyncEnd(IntSize aSize, WebRenderParentCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, uint64_t transactionId,
ByteBuffer aDL, WrBuiltDisplayListDescriptor aDLDesc, ByteBuffer aAux, WrAuxiliaryListsDescriptor aAuxDesc);
ByteBuffer aDL, WrBuiltDisplayListDescriptor aDLDesc, ByteBuffer aAux, WrAuxiliaryListsDescriptor aAuxDesc,
WebRenderScrollData aScrollData);
sync DPGetSnapshot(PTexture texture);
async AddExternalImageId(uint64_t aImageId, CompositableHandle aHandle);
async AddExternalImageIdForCompositable(uint64_t aImageId, CompositableHandle aHandle);
async RemoveExternalImageId(uint64_t aImageId);
async AddExternalImageId(ExternalImageId aImageId, CompositableHandle aHandle);
async AddExternalImageIdForCompositable(ExternalImageId aImageId, CompositableHandle aHandle);
async RemoveExternalImageId(ExternalImageId aImageId);
async SetLayerObserverEpoch(uint64_t layerObserverEpoch);
async ClearCachedResources();
// Schedule a composite if one isn't already scheduled.

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

@ -51,6 +51,8 @@ public:
virtual void CancelWaitForRecycle(uint64_t aTextureId) = 0;
virtual wr::MaybeExternalImageId GetNextExternalImageId() { return Nothing(); }
protected:
virtual ~LayersIPCChannel() {}
};
@ -69,7 +71,8 @@ public:
const SurfaceDescriptor& aSharedData,
LayersBackend aLayersBackend,
TextureFlags aFlags,
uint64_t aSerial) = 0;
uint64_t aSerial,
wr::MaybeExternalImageId& aExternalImageId) = 0;
};
} // namespace layers

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

@ -107,7 +107,8 @@ PTextureChild*
VideoBridgeChild::CreateTexture(const SurfaceDescriptor& aSharedData,
LayersBackend aLayersBackend,
TextureFlags aFlags,
uint64_t aSerial)
uint64_t aSerial,
wr::MaybeExternalImageId& aExternalImageId)
{
MOZ_ASSERT(CanSend());
return SendPTextureConstructor(aSharedData, aLayersBackend, aFlags, aSerial);

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

@ -48,7 +48,8 @@ public:
PTextureChild* CreateTexture(const SurfaceDescriptor& aSharedData,
LayersBackend aLayersBackend,
TextureFlags aFlags,
uint64_t aSerial) override;
uint64_t aSerial,
wr::MaybeExternalImageId& aExternalImageId) override;
// ClientIPCAllocator
base::ProcessId GetParentPid() const override { return OtherPid(); }

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

@ -62,7 +62,7 @@ VideoBridgeParent::AllocPTextureParent(const SurfaceDescriptor& aSharedData,
const uint64_t& aSerial)
{
PTextureParent* parent =
TextureHost::CreateIPDLActor(this, aSharedData, aLayersBackend, aFlags, aSerial);
TextureHost::CreateIPDLActor(this, aSharedData, aLayersBackend, aFlags, aSerial, Nothing());
mTextureMap[aSerial] = parent;
return parent;
}

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

@ -9,19 +9,30 @@ include LayersSurfaces;
include LayersMessages;
include protocol PTexture;
using mozilla::wr::ExternalImageId from "mozilla/webrender/WebRenderTypes.h";
using mozilla::wr::ImageKey from "mozilla/webrender/WebRenderTypes.h";
namespace mozilla {
namespace layers {
struct OpAddExternalImage {
uint64_t externalImageId;
ExternalImageId externalImageId;
ImageKey key;
};
struct OpAddCompositorAnimations {
CompositorAnimations data;
};
struct OpRemoveCompositorAnimations {
uint64_t id;
};
union WebRenderParentCommand {
OpAddExternalImage;
CompositableOperation;
OpAddCompositorAnimations;
OpRemoveCompositorAnimations;
};
} // namespace

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

@ -198,14 +198,19 @@ EXPORTS.mozilla.layers += [
'TextureSourceProvider.h',
'TextureWrapperImage.h',
'TransactionIdAllocator.h',
'UpdateImageHelper.h',
'wr/StackingContextHelper.h',
'wr/WebRenderBridgeChild.h',
'wr/WebRenderBridgeParent.h',
'wr/WebRenderCompositableHolder.h',
'wr/WebRenderDisplayItemLayer.h',
'wr/WebRenderImageHost.h',
'wr/WebRenderLayer.h',
'wr/WebRenderLayerManager.h',
'wr/WebRenderLayersLogging.h',
'wr/WebRenderMessageUtils.h',
'wr/WebRenderScrollData.h',
'wr/WebRenderScrollDataWrapper.h',
'wr/WebRenderTextureHost.h',
]
@ -389,6 +394,7 @@ UNIFIED_SOURCES += [
'SourceSurfaceVolatileData.cpp',
'TextureSourceProvider.cpp',
'TextureWrapperImage.cpp',
'wr/StackingContextHelper.cpp',
'wr/WebRenderBridgeChild.cpp',
'wr/WebRenderBridgeParent.cpp',
'wr/WebRenderCanvasLayer.cpp',
@ -398,9 +404,11 @@ UNIFIED_SOURCES += [
'wr/WebRenderDisplayItemLayer.cpp',
'wr/WebRenderImageHost.cpp',
'wr/WebRenderImageLayer.cpp',
'wr/WebRenderLayer.cpp',
'wr/WebRenderLayerManager.cpp',
'wr/WebRenderLayersLogging.cpp',
'wr/WebRenderPaintedLayer.cpp',
'wr/WebRenderScrollData.cpp',
'wr/WebRenderTextLayer.cpp',
# XXX here are some unified build error.
#'wr/WebRenderTextureHost.cpp'

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

@ -0,0 +1,56 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/layers/StackingContextHelper.h"
#include "mozilla/layers/WebRenderLayer.h"
namespace mozilla {
namespace layers {
StackingContextHelper::StackingContextHelper(wr::DisplayListBuilder& aBuilder,
WebRenderLayer* aLayer,
const Maybe<gfx::Matrix4x4>& aTransform)
: mBuilder(&aBuilder)
{
LayerRect scBounds = aLayer->RelativeToParent(aLayer->BoundsForStackingContext());
Layer* layer = aLayer->GetLayer();
gfx::Matrix4x4 transform = aTransform.valueOr(layer->GetTransform());
mBuilder->PushStackingContext(wr::ToWrRect(scBounds),
1.0f,
transform,
wr::ToWrMixBlendMode(layer->GetMixBlendMode()));
mOrigin = aLayer->Bounds().TopLeft();
}
StackingContextHelper::StackingContextHelper(wr::DisplayListBuilder& aBuilder,
WebRenderLayer* aLayer,
uint64_t aAnimationsId,
float* aOpacityPtr,
gfx::Matrix4x4* aTransformPtr)
: mBuilder(&aBuilder)
{
LayerRect scBounds = aLayer->RelativeToParent(aLayer->BoundsForStackingContext());
mBuilder->PushStackingContext(wr::ToWrRect(scBounds),
aAnimationsId,
aOpacityPtr,
aTransformPtr,
wr::ToWrMixBlendMode(aLayer->GetLayer()->GetMixBlendMode()));
mOrigin = aLayer->Bounds().TopLeft();
}
StackingContextHelper::~StackingContextHelper()
{
mBuilder->PopStackingContext();
}
WrRect
StackingContextHelper::ToRelativeWrRect(const LayerRect& aRect)
{
return wr::ToWrRect(aRect - mOrigin);
}
} // namespace layers
} // namespace mozilla

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

@ -0,0 +1,59 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GFX_STACKINGCONTEXTHELPER_H
#define GFX_STACKINGCONTEXTHELPER_H
#include "mozilla/Attributes.h"
#include "mozilla/gfx/MatrixFwd.h"
#include "mozilla/webrender/WebRenderAPI.h"
#include "mozilla/webrender/WebRenderTypes.h"
#include "Units.h"
namespace mozilla {
namespace layers {
class WebRenderLayer;
/**
* This is a helper class that pushes/pops a stacking context, and manages
* some of the coordinate space transformations needed.
*/
class MOZ_RAII StackingContextHelper
{
public:
// Pushes a stacking context onto the provided DisplayListBuilder. It uses
// the transform if provided, otherwise takes the transform from the layer.
// It also takes the mix-blend-mode and bounds from the layer, and uses 1.0
// for the opacity.
StackingContextHelper(wr::DisplayListBuilder& aBuilder,
WebRenderLayer* aLayer,
const Maybe<gfx::Matrix4x4>& aTransform = Nothing());
// Alternate constructor which invokes the version of PushStackingContext
// for animations.
StackingContextHelper(wr::DisplayListBuilder& aBuilder,
WebRenderLayer* aLayer,
uint64_t aAnimationsId,
float* aOpacityPtr,
gfx::Matrix4x4* aTransformPtr);
// Pops the stacking context
~StackingContextHelper();
// When this StackingContextHelper is in scope, this function can be used
// to convert a rect from the layer system's coordinate space to a WrRect
// that is relative to the stacking context. This is useful because most
// things that are pushed inside the stacking context need to be relative
// to the stacking context.
WrRect ToRelativeWrRect(const LayerRect& aRect);
private:
wr::DisplayListBuilder* mBuilder;
LayerPoint mOrigin;
};
} // namespace layers
} // namespace mozilla
#endif /* GFX_STACKINGCONTEXTHELPER_H */

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

@ -65,7 +65,6 @@ bool
WebRenderBridgeChild::DPBegin(const gfx::IntSize& aSize)
{
MOZ_ASSERT(!mDestroyed);
MOZ_ASSERT(!mIsInTransaction);
UpdateFwdTransactionId();
this->SendDPBegin(aSize);
@ -76,11 +75,8 @@ WebRenderBridgeChild::DPBegin(const gfx::IntSize& aSize)
}
void
WebRenderBridgeChild::DPEnd(wr::DisplayListBuilder &aBuilder, const gfx::IntSize& aSize, bool aIsSync, uint64_t aTransactionId)
WebRenderBridgeChild::ClearReadLocks()
{
MOZ_ASSERT(!mDestroyed);
MOZ_ASSERT(mIsInTransaction);
for (nsTArray<ReadLockInit>& locks : mReadLocks) {
if (locks.Length()) {
if (!SendInitReadLocks(locks)) {
@ -90,61 +86,73 @@ WebRenderBridgeChild::DPEnd(wr::DisplayListBuilder &aBuilder, const gfx::IntSize
}
}
mReadLocks.Clear();
}
void
WebRenderBridgeChild::DPEnd(wr::DisplayListBuilder &aBuilder,
const gfx::IntSize& aSize,
bool aIsSync,
uint64_t aTransactionId,
const WebRenderScrollData& aScrollData)
{
MOZ_ASSERT(!mDestroyed);
MOZ_ASSERT(mIsInTransaction);
wr::BuiltDisplayList dl = aBuilder.Finalize();
ByteBuffer dlData(Move(dl.dl));
ByteBuffer auxData(Move(dl.aux));
if (aIsSync) {
this->SendDPSyncEnd(aSize, mParentCommands, mDestroyedActors, GetFwdTransactionId(), aTransactionId,
dlData, dl.dl_desc, auxData, dl.aux_desc);
dlData, dl.dl_desc, auxData, dl.aux_desc, aScrollData);
} else {
this->SendDPEnd(aSize, mParentCommands, mDestroyedActors, GetFwdTransactionId(), aTransactionId,
dlData, dl.dl_desc, auxData, dl.aux_desc);
dlData, dl.dl_desc, auxData, dl.aux_desc, aScrollData);
}
mParentCommands.Clear();
mDestroyedActors.Clear();
mReadLocks.Clear();
mIsInTransaction = false;
}
uint64_t
wr::ExternalImageId
WebRenderBridgeChild::GetNextExternalImageId()
{
return GetCompositorBridgeChild()->GetNextExternalImageId();
wr::MaybeExternalImageId id = GetCompositorBridgeChild()->GetNextExternalImageId();
MOZ_RELEASE_ASSERT(id.isSome());
return id.value();
}
uint64_t
wr::ExternalImageId
WebRenderBridgeChild::AllocExternalImageId(const CompositableHandle& aHandle)
{
MOZ_ASSERT(!mDestroyed);
uint64_t imageId = GetNextExternalImageId();
wr::ExternalImageId imageId = GetNextExternalImageId();
SendAddExternalImageId(imageId, aHandle);
return imageId;
}
uint64_t
wr::ExternalImageId
WebRenderBridgeChild::AllocExternalImageIdForCompositable(CompositableClient* aCompositable)
{
MOZ_ASSERT(!mDestroyed);
MOZ_ASSERT(aCompositable->IsConnected());
uint64_t imageId = GetNextExternalImageId();
wr::ExternalImageId imageId = GetNextExternalImageId();
SendAddExternalImageIdForCompositable(imageId, aCompositable->GetIPCHandle());
return imageId;
}
void
WebRenderBridgeChild::DeallocExternalImageId(uint64_t aImageId)
WebRenderBridgeChild::DeallocExternalImageId(wr::ExternalImageId& aImageId)
{
if (mDestroyed) {
// This can happen if the IPC connection was torn down, because, e.g.
// the GPU process died.
return;
}
MOZ_ASSERT(aImageId);
SendRemoveExternalImageId(aImageId);
}
@ -170,7 +178,7 @@ WriteFontFileData(const uint8_t* aData, uint32_t aLength, uint32_t aIndex,
void
WebRenderBridgeChild::PushGlyphs(wr::DisplayListBuilder& aBuilder, const nsTArray<GlyphArray>& aGlyphs,
gfx::ScaledFont* aFont, const gfx::Point& aOffset, const gfx::Rect& aBounds,
gfx::ScaledFont* aFont, const LayerPoint& aOffset, const gfx::Rect& aBounds,
const gfx::Rect& aClip)
{
MOZ_ASSERT(aFont);

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

@ -60,7 +60,9 @@ public:
void AddWebRenderParentCommands(const nsTArray<WebRenderParentCommand>& aCommands);
bool DPBegin(const gfx::IntSize& aSize);
void DPEnd(wr::DisplayListBuilder &aBuilder, const gfx::IntSize& aSize, bool aIsSync, uint64_t aTransactionId);
void DPEnd(wr::DisplayListBuilder &aBuilder, const gfx::IntSize& aSize,
bool aIsSync, uint64_t aTransactionId,
const WebRenderScrollData& aScrollData);
CompositorBridgeChild* GetCompositorBridgeChild();
@ -70,9 +72,9 @@ public:
TextureForwarder* GetTextureForwarder() override;
LayersIPCActor* GetLayersIPCActor() override;
uint64_t AllocExternalImageId(const CompositableHandle& aHandle);
uint64_t AllocExternalImageIdForCompositable(CompositableClient* aCompositable);
void DeallocExternalImageId(uint64_t aImageId);
wr::ExternalImageId AllocExternalImageId(const CompositableHandle& aHandle);
wr::ExternalImageId AllocExternalImageIdForCompositable(CompositableClient* aCompositable);
void DeallocExternalImageId(wr::ExternalImageId& aImageId);
/**
* Clean this up, finishing with SendShutDown() which will cause __delete__
@ -90,19 +92,20 @@ public:
}
void PushGlyphs(wr::DisplayListBuilder& aBuilder, const nsTArray<GlyphArray>& aGlyphs,
gfx::ScaledFont* aFont, const gfx::Point& aOffset, const gfx::Rect& aBounds,
gfx::ScaledFont* aFont, const LayerPoint& aOffset, const gfx::Rect& aBounds,
const gfx::Rect& aClip);
wr::FontKey GetFontKeyForScaledFont(gfx::ScaledFont* aScaledFont);
void RemoveExpiredFontKeys();
void ClearReadLocks();
private:
friend class CompositorBridgeChild;
~WebRenderBridgeChild() {}
uint64_t GetNextExternalImageId();
wr::ExternalImageId GetNextExternalImageId();
// CompositableForwarder
void Connect(CompositableClient* aCompositable,

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

@ -7,9 +7,12 @@
#include "mozilla/layers/WebRenderBridgeParent.h"
#include "CompositableHost.h"
#include "gfxPrefs.h"
#include "GLContext.h"
#include "GLContextProvider.h"
#include "mozilla/Range.h"
#include "mozilla/layers/AnimationHelper.h"
#include "mozilla/layers/APZCTreeManager.h"
#include "mozilla/layers/Compositor.h"
#include "mozilla/layers/CompositorBridgeParent.h"
#include "mozilla/layers/CompositorThread.h"
@ -18,7 +21,9 @@
#include "mozilla/layers/ImageDataSerializer.h"
#include "mozilla/layers/TextureHost.h"
#include "mozilla/layers/WebRenderCompositableHolder.h"
#include "mozilla/layers/WebRenderImageHost.h"
#include "mozilla/layers/WebRenderTextureHost.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/webrender/RenderThread.h"
#include "mozilla/widget/CompositorWidget.h"
@ -218,7 +223,7 @@ WebRenderBridgeParent::RecvAddRawFont(const wr::FontKey& aFontKey,
}
MOZ_ASSERT(mApi);
auto slice = aBuffer.AsSlice();
mApi->AddRawFont(aFontKey, slice);
mApi->AddRawFont(aFontKey, slice, aFontIndex);
return IPC_OK();
}
@ -282,7 +287,8 @@ WebRenderBridgeParent::HandleDPEnd(const gfx::IntSize& aSize,
const ByteBuffer& dl,
const WrBuiltDisplayListDescriptor& dlDesc,
const ByteBuffer& aux,
const WrAuxiliaryListsDescriptor& auxDesc)
const WrAuxiliaryListsDescriptor& auxDesc,
const WebRenderScrollData& aScrollData)
{
UpdateFwdTransactionId(aFwdTransactionId);
AutoClearReadLocks clearLocks(mReadLocks);
@ -301,6 +307,58 @@ WebRenderBridgeParent::HandleDPEnd(const gfx::IntSize& aSize,
ProcessWebRenderCommands(aSize, aCommands, wr::NewEpoch(mWrEpoch),
dl, dlDesc, aux, auxDesc);
HoldPendingTransactionId(mWrEpoch, aTransactionId);
mScrollData = aScrollData;
UpdateAPZ();
}
void
WebRenderBridgeParent::UpdateAPZ()
{
if (!mCompositorBridge) {
return;
}
CompositorBridgeParent* cbp;
uint64_t rootLayersId;
WebRenderBridgeParent* rootWrbp;
if (mWidget) {
// This WebRenderBridgeParent is attached to the root
// CompositorBridgeParent.
cbp = static_cast<CompositorBridgeParent*>(mCompositorBridge);
rootLayersId = wr::AsUint64(mPipelineId);
rootWrbp = this;
} else {
// This WebRenderBridgeParent is attached to a
// CrossProcessCompositorBridgeParent so we have an extra level of
// indirection to unravel.
uint64_t layersId = wr::AsUint64(mPipelineId);
CompositorBridgeParent::LayerTreeState* lts =
CompositorBridgeParent::GetIndirectShadowTree(layersId);
MOZ_ASSERT(lts);
cbp = lts->mParent;
rootLayersId = cbp->RootLayerTreeId();
lts = CompositorBridgeParent::GetIndirectShadowTree(rootLayersId);
MOZ_ASSERT(lts);
rootWrbp = lts->mWrBridge.get();
}
MOZ_ASSERT(cbp);
if (!rootWrbp) {
return;
}
if (RefPtr<APZCTreeManager> apzc = cbp->GetAPZCTreeManager()) {
apzc->UpdateHitTestingTree(rootLayersId, rootWrbp->GetScrollData(),
mScrollData.IsFirstPaint(), wr::AsUint64(mPipelineId),
/* TODO: propagate paint sequence number */ 0);
}
}
const WebRenderScrollData&
WebRenderBridgeParent::GetScrollData() const
{
MOZ_ASSERT(mozilla::layers::CompositorThreadHolder::IsInCompositorThread());
return mScrollData;
}
mozilla::ipc::IPCResult
@ -312,10 +370,11 @@ WebRenderBridgeParent::RecvDPEnd(const gfx::IntSize& aSize,
const ByteBuffer& dl,
const WrBuiltDisplayListDescriptor& dlDesc,
const ByteBuffer& aux,
const WrAuxiliaryListsDescriptor& auxDesc)
const WrAuxiliaryListsDescriptor& auxDesc,
const WebRenderScrollData& aScrollData)
{
HandleDPEnd(aSize, Move(aCommands), Move(aToDestroy), aFwdTransactionId, aTransactionId,
dl, dlDesc, aux, auxDesc);
dl, dlDesc, aux, auxDesc, aScrollData);
return IPC_OK();
}
@ -328,10 +387,11 @@ WebRenderBridgeParent::RecvDPSyncEnd(const gfx::IntSize &aSize,
const ByteBuffer& dl,
const WrBuiltDisplayListDescriptor& dlDesc,
const ByteBuffer& aux,
const WrAuxiliaryListsDescriptor& auxDesc)
const WrAuxiliaryListsDescriptor& auxDesc,
const WebRenderScrollData& aScrollData)
{
HandleDPEnd(aSize, Move(aCommands), Move(aToDestroy), aFwdTransactionId, aTransactionId,
dl, dlDesc, aux, auxDesc);
dl, dlDesc, aux, auxDesc, aScrollData);
return IPC_OK();
}
@ -343,6 +403,7 @@ WebRenderBridgeParent::ProcessWebRenderCommands(const gfx::IntSize &aSize,
const ByteBuffer& aux,
const WrAuxiliaryListsDescriptor& auxDesc)
{
mCompositableHolder->SetCompositionTime(TimeStamp::Now());
for (InfallibleTArray<WebRenderParentCommand>::index_type i = 0; i < aCommands.Length(); ++i) {
const WebRenderParentCommand& cmd = aCommands[i];
@ -350,17 +411,17 @@ WebRenderBridgeParent::ProcessWebRenderCommands(const gfx::IntSize &aSize,
case WebRenderParentCommand::TOpAddExternalImage: {
const OpAddExternalImage& op = cmd.get_OpAddExternalImage();
wr::ImageKey key = op.key();
MOZ_ASSERT(mExternalImageIds.Get(op.externalImageId()).get());
MOZ_ASSERT(mExternalImageIds.Get(wr::AsUint64(op.externalImageId())).get());
MOZ_ASSERT(!mActiveKeys.Get(wr::AsUint64(key), nullptr));
mActiveKeys.Put(wr::AsUint64(key), key);
RefPtr<CompositableHost> host = mExternalImageIds.Get(op.externalImageId());
RefPtr<WebRenderImageHost> host = mExternalImageIds.Get(wr::AsUint64(op.externalImageId()));
if (!host) {
NS_ERROR("CompositableHost does not exist");
break;
}
// XXX select Texture for video in CompositeToTarget().
TextureHost* texture = host->GetAsTextureHost();
TextureHost* texture = host->GetAsTextureHostForComposite();
if (!texture) {
NS_ERROR("TextureHost does not exist");
break;
@ -412,6 +473,31 @@ WebRenderBridgeParent::ProcessWebRenderCommands(const gfx::IntSize &aSize,
}
break;
}
case WebRenderParentCommand::TOpAddCompositorAnimations: {
const OpAddCompositorAnimations& op = cmd.get_OpAddCompositorAnimations();
CompositorAnimations data(Move(op.data()));
if (data.animations().Length()) {
uint64_t id = mWidget ? 0 : wr::AsUint64(mPipelineId);
CompositorAnimationStorage* storage =
mCompositorBridge->GetAnimationStorage(id);
if (storage) {
storage->SetAnimations(data.id(), data.animations());
}
}
break;
}
case WebRenderParentCommand::TOpRemoveCompositorAnimations: {
const OpRemoveCompositorAnimations& op = cmd.get_OpRemoveCompositorAnimations();
if (op.id()) {
uint64_t id = mWidget ? 0 : wr::AsUint64(mPipelineId);
CompositorAnimationStorage* storage =
mCompositorBridge->GetAnimationStorage(id);
if (storage) {
storage->ClearById(op.id());
}
}
break;
}
default: {
// other commands are handle on the child
break;
@ -485,14 +571,14 @@ WebRenderBridgeParent::RecvDPGetSnapshot(PTextureParent* aTexture)
}
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvAddExternalImageId(const uint64_t& aImageId,
WebRenderBridgeParent::RecvAddExternalImageId(const ExternalImageId& aImageId,
const CompositableHandle& aHandle)
{
if (mDestroyed) {
return IPC_OK();
}
MOZ_ASSERT(!mExternalImageIds.Get(aImageId).get());
MOZ_ASSERT(!mExternalImageIds.Get(wr::AsUint64(aImageId)).get());
ImageBridgeParent* imageBridge = ImageBridgeParent::GetInstance(OtherPid());
if (!imageBridge) {
@ -504,45 +590,53 @@ WebRenderBridgeParent::RecvAddExternalImageId(const uint64_t& aImageId,
return IPC_FAIL_NO_REASON(this);
}
MOZ_ASSERT(host->AsWebRenderImageHost());
if (!host->AsWebRenderImageHost()) {
WebRenderImageHost* wrHost = host->AsWebRenderImageHost();
if (!wrHost) {
NS_ERROR("Incompatible CompositableHost");
return IPC_OK();
}
mExternalImageIds.Put(aImageId, host);
wrHost->SetWrCompositableHolder(mCompositableHolder);
mExternalImageIds.Put(wr::AsUint64(aImageId), wrHost);
return IPC_OK();
}
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvAddExternalImageIdForCompositable(const uint64_t& aImageId,
WebRenderBridgeParent::RecvAddExternalImageIdForCompositable(const ExternalImageId& aImageId,
const CompositableHandle& aHandle)
{
if (mDestroyed) {
return IPC_OK();
}
MOZ_ASSERT(!mExternalImageIds.Get(aImageId).get());
MOZ_ASSERT(!mExternalImageIds.Get(wr::AsUint64(aImageId)).get());
RefPtr<CompositableHost> host = FindCompositable(aHandle);
MOZ_ASSERT(host->AsWebRenderImageHost());
if (!host->AsWebRenderImageHost()) {
WebRenderImageHost* wrHost = host->AsWebRenderImageHost();
if (!wrHost) {
NS_ERROR("Incompatible CompositableHost");
return IPC_OK();
}
mExternalImageIds.Put(aImageId, host);
wrHost->SetWrCompositableHolder(mCompositableHolder);
mExternalImageIds.Put(wr::AsUint64(aImageId), wrHost);
return IPC_OK();
}
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvRemoveExternalImageId(const uint64_t& aImageId)
WebRenderBridgeParent::RecvRemoveExternalImageId(const ExternalImageId& aImageId)
{
if (mDestroyed) {
return IPC_OK();
}
MOZ_ASSERT(mExternalImageIds.Get(aImageId).get());
mExternalImageIds.Remove(aImageId);
MOZ_ASSERT(mExternalImageIds.Get(wr::AsUint64(aImageId)).get());
WebRenderImageHost* wrHost = mExternalImageIds.Get(wr::AsUint64(aImageId)).get();
if (wrHost) {
wrHost->SetWrCompositableHolder(nullptr);
}
mExternalImageIds.Remove(wr::AsUint64(aImageId));
return IPC_OK();
}
@ -577,13 +671,59 @@ WebRenderBridgeParent::ActorDestroy(ActorDestroyReason aWhy)
Destroy();
}
void
WebRenderBridgeParent::SampleAnimations(nsTArray<WrOpacityProperty>& aOpacityArray,
nsTArray<WrTransformProperty>& aTransformArray)
{
uint64_t id = mWidget ? 0 : wr::AsUint64(mPipelineId);
CompositorAnimationStorage* storage =
mCompositorBridge->GetAnimationStorage(id);
AnimationHelper::SampleAnimations(storage,
mCompositorScheduler->
GetLastComposeTime());
// return the animated data if has
if (storage->AnimatedValueCount()) {
for(auto iter = storage->ConstAnimatedValueTableIter();
!iter.Done(); iter.Next()) {
AnimatedValue * value = iter.UserData();
if (value->mType == AnimatedValue::TRANSFORM) {
aTransformArray.AppendElement(
wr::ToWrTransformProperty(iter.Key(), value->mTransform.mTransformInDevSpace));
} else if (value->mType == AnimatedValue::OPACITY) {
aOpacityArray.AppendElement(
wr::ToWrOpacityProperty(iter.Key(), value->mOpacity));
}
}
}
}
void
WebRenderBridgeParent::CompositeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect)
{
if (mPaused) {
return;
}
if (gfxPrefs::WebRenderOMTAEnabled()) {
nsTArray<WrOpacityProperty> opacityArray;
nsTArray<WrTransformProperty> transformArray;
SampleAnimations(opacityArray, transformArray);
if (!transformArray.IsEmpty() || !opacityArray.IsEmpty()) {
mApi->GenerateFrame(opacityArray, transformArray);
ScheduleComposition();
return;
}
}
mApi->GenerateFrame();
// XXX Enable it when async video is supported.
// if (!mCompositableHolder->GetCompositeUntilTime().IsNull()) {
// ScheduleComposition();
// }
}
void
@ -704,6 +844,9 @@ WebRenderBridgeParent::ClearResources()
}
}
mCompositableHolder->RemovePipeline(mPipelineId);
for (auto iter = mExternalImageIds.Iter(); !iter.Done(); iter.Next()) {
iter.Data()->SetWrCompositableHolder(nullptr);
}
mExternalImageIds.Clear();
if (mWidget && mCompositorScheduler) {

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

@ -37,6 +37,7 @@ class Compositor;
class CompositorBridgeParentBase;
class CompositorVsyncScheduler;
class WebRenderCompositableHolder;
class WebRenderImageHost;
class WebRenderBridgeParent final : public PWebRenderBridgeParent
, public CompositorVsyncSchedulerOwner
@ -91,7 +92,8 @@ public:
const ByteBuffer& dl,
const WrBuiltDisplayListDescriptor& dlDesc,
const ByteBuffer& aux,
const WrAuxiliaryListsDescriptor& auxDesc) override;
const WrAuxiliaryListsDescriptor& auxDesc,
const WebRenderScrollData& aScrollData) override;
mozilla::ipc::IPCResult RecvDPSyncEnd(const gfx::IntSize& aSize,
InfallibleTArray<WebRenderParentCommand>&& aCommands,
InfallibleTArray<OpDestroy>&& aToDestroy,
@ -100,14 +102,15 @@ public:
const ByteBuffer& dl,
const WrBuiltDisplayListDescriptor& dlDesc,
const ByteBuffer& aux,
const WrAuxiliaryListsDescriptor& auxDesc) override;
const WrAuxiliaryListsDescriptor& auxDesc,
const WebRenderScrollData& aScrollData) override;
mozilla::ipc::IPCResult RecvDPGetSnapshot(PTextureParent* aTexture) override;
mozilla::ipc::IPCResult RecvAddExternalImageId(const uint64_t& aImageId,
mozilla::ipc::IPCResult RecvAddExternalImageId(const ExternalImageId& aImageId,
const CompositableHandle& aHandle) override;
mozilla::ipc::IPCResult RecvAddExternalImageIdForCompositable(const uint64_t& aImageId,
mozilla::ipc::IPCResult RecvAddExternalImageIdForCompositable(const ExternalImageId& aImageId,
const CompositableHandle& aHandle) override;
mozilla::ipc::IPCResult RecvRemoveExternalImageId(const uint64_t& aImageId) override;
mozilla::ipc::IPCResult RecvRemoveExternalImageId(const ExternalImageId& aImageId) override;
mozilla::ipc::IPCResult RecvSetLayerObserverEpoch(const uint64_t& aLayerObserverEpoch) override;
mozilla::ipc::IPCResult RecvClearCachedResources() override;
@ -158,6 +161,9 @@ public:
return mIdNameSpace;
}
void UpdateAPZ();
const WebRenderScrollData& GetScrollData() const;
private:
virtual ~WebRenderBridgeParent();
@ -179,7 +185,11 @@ private:
const ByteBuffer& dl,
const WrBuiltDisplayListDescriptor& dlDesc,
const ByteBuffer& aux,
const WrAuxiliaryListsDescriptor& auxDesc);
const WrAuxiliaryListsDescriptor& auxDesc,
const WebRenderScrollData& aScrollData);
void SampleAnimations(nsTArray<WrOpacityProperty>& aOpacityArray,
nsTArray<WrTransformProperty>& aTransformArray);
private:
struct PendingTransactionId {
@ -200,7 +210,7 @@ private:
std::vector<wr::ImageKey> mKeysToDelete;
// XXX How to handle active keys of non-ExternalImages?
nsDataHashtable<nsUint64HashKey, wr::ImageKey> mActiveKeys;
nsDataHashtable<nsUint64HashKey, RefPtr<CompositableHost>> mExternalImageIds;
nsDataHashtable<nsUint64HashKey, RefPtr<WebRenderImageHost>> mExternalImageIds;
nsTArray<ImageCompositeNotificationInfo> mImageCompositeNotifications;
// These fields keep track of the latest layer observer epoch values in the child and the
@ -217,6 +227,9 @@ private:
bool mPaused;
bool mDestroyed;
// Can only be accessed on the compositor thread.
WebRenderScrollData mScrollData;
static uint32_t sIdNameSpace;
};

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

@ -12,6 +12,7 @@
#include "GLScreenBuffer.h"
#include "LayersLogging.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/layers/StackingContextHelper.h"
#include "mozilla/layers/TextureClientSharedSurface.h"
#include "mozilla/layers/WebRenderBridgeChild.h"
#include "PersistentBufferProvider.h"
@ -26,8 +27,8 @@ WebRenderCanvasLayer::~WebRenderCanvasLayer()
{
MOZ_COUNT_DTOR(WebRenderCanvasLayer);
if (mExternalImageId) {
WrBridge()->DeallocExternalImageId(mExternalImageId);
if (mExternalImageId.isSome()) {
WrBridge()->DeallocExternalImageId(mExternalImageId.ref());
}
}
@ -50,48 +51,40 @@ WebRenderCanvasLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
{
UpdateCompositableClient();
if (!mExternalImageId) {
mExternalImageId = WrBridge()->AllocExternalImageIdForCompositable(mCanvasClient);
if (mExternalImageId.isNothing()) {
mExternalImageId = Some(WrBridge()->AllocExternalImageIdForCompositable(mCanvasClient));
}
MOZ_ASSERT(mExternalImageId);
gfx::Matrix4x4 transform = GetTransform();
Maybe<gfx::Matrix4x4> transform;
const bool needsYFlip = (mOriginPos == gl::OriginPos::BottomLeft);
if (needsYFlip) {
transform.PreTranslate(0, mBounds.height, 0).PreScale(1, -1, 1);
transform = Some(GetTransform().PreTranslate(0, mBounds.height, 0).PreScale(1, -1, 1));
}
gfx::Rect relBounds = GetWrRelBounds();
gfx::Rect rect = RelativeToVisible(gfx::Rect(0, 0, mBounds.width, mBounds.height));
StackingContextHelper sc(aBuilder, this, transform);
gfx::Rect clipRect = GetWrClipRect(rect);
LayerRect rect(0, 0, mBounds.width, mBounds.height);
DumpLayerInfo("CanvasLayer", rect);
LayerRect clipRect = ClipRect().valueOr(rect);
Maybe<WrImageMask> mask = BuildWrMaskLayer(true);
WrClipRegion clip = aBuilder.BuildClipRegion(wr::ToWrRect(clipRect), mask.ptrOr(nullptr));
WrClipRegion clip = aBuilder.BuildClipRegion(
sc.ToRelativeWrRect(clipRect),
mask.ptrOr(nullptr));
wr::ImageRendering filter = wr::ToImageRendering(mSamplingFilter);
wr::MixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
DumpLayerInfo("CanvasLayer", rect);
if (gfxPrefs::LayersDump()) {
printf_stderr("CanvasLayer %p texture-filter=%s\n",
this->GetLayer(),
Stringify(filter).c_str());
}
WrImageKey key;
key.mNamespace = WrBridge()->GetNamespace();
key.mHandle = WrBridge()->GetNextResourceId();
WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId, key));
WrImageKey key = GetImageKey();
WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId.value(), key));
Manager()->AddImageKeyForDiscard(key);
aBuilder.PushStackingContext(wr::ToWrRect(relBounds),
1.0f,
//GetAnimations(),
transform,
mixBlendMode);
aBuilder.PushImage(wr::ToWrRect(rect), clip, filter, key);
aBuilder.PopStackingContext();
aBuilder.PushImage(sc.ToRelativeWrRect(rect), clip, filter, key);
}
void

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

@ -6,8 +6,9 @@
#ifndef GFX_WEBRENDERCANVASLAYER_H
#define GFX_WEBRENDERCANVASLAYER_H
#include "mozilla/layers/WebRenderLayer.h"
#include "mozilla/layers/WebRenderLayerManager.h"
#include "ShareableCanvasLayer.h"
#include "WebRenderLayerManager.h"
namespace mozilla {
namespace gfx {
@ -22,7 +23,6 @@ class WebRenderCanvasLayer : public WebRenderLayer,
public:
explicit WebRenderCanvasLayer(WebRenderLayerManager* aLayerManager)
: ShareableCanvasLayer(aLayerManager, static_cast<WebRenderLayer*>(this))
, mExternalImageId(0)
{
MOZ_COUNT_CTOR(WebRenderCanvasLayer);
}
@ -45,7 +45,7 @@ public:
void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
protected:
uint64_t mExternalImageId;
wr::MaybeExternalImageId mExternalImageId;
};
} // namespace layers

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

@ -9,6 +9,7 @@
#include "LayersLogging.h"
#include "mozilla/webrender/webrender_ffi.h"
#include "mozilla/webrender/WebRenderTypes.h"
#include "mozilla/layers/StackingContextHelper.h"
#include "mozilla/layers/WebRenderBridgeChild.h"
namespace mozilla {
@ -19,25 +20,18 @@ using namespace mozilla::gfx;
void
WebRenderColorLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
{
gfx::Matrix4x4 transform = GetTransform();
gfx::Rect relBounds = GetWrRelBounds();
gfx::Rect rect = GetWrBoundsRect();
gfx::Rect clipRect = GetWrClipRect(rect);
Maybe<WrImageMask> mask = BuildWrMaskLayer(true);
WrClipRegion clip = aBuilder.BuildClipRegion(wr::ToWrRect(clipRect), mask.ptrOr(nullptr));
wr::MixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
StackingContextHelper sc(aBuilder, this);
LayerRect rect = Bounds();
DumpLayerInfo("ColorLayer", rect);
aBuilder.PushStackingContext(wr::ToWrRect(relBounds),
1.0f,
//GetAnimations(),
transform,
mixBlendMode);
aBuilder.PushRect(wr::ToWrRect(rect), clip, wr::ToWrColor(mColor));
aBuilder.PopStackingContext();
LayerRect clipRect = ClipRect().valueOr(rect);
Maybe<WrImageMask> mask = BuildWrMaskLayer(true);
WrClipRegion clip = aBuilder.BuildClipRegion(
sc.ToRelativeWrRect(clipRect),
mask.ptrOr(nullptr));
aBuilder.PushRect(sc.ToRelativeWrRect(rect), clip, wr::ToWrColor(mColor));
}
} // namespace layers

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

@ -7,7 +7,8 @@
#define GFX_WEBRENDERCOLORLAYER_H
#include "Layers.h"
#include "WebRenderLayerManager.h"
#include "mozilla/layers/WebRenderLayer.h"
#include "mozilla/layers/WebRenderLayerManager.h"
namespace mozilla {
namespace layers {

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

@ -39,6 +39,26 @@ public:
void HoldExternalImage(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch, WebRenderTextureHost* aTexture);
void Update(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch);
TimeStamp GetCompositionTime() const {
return mCompositionTime;
}
void SetCompositionTime(TimeStamp aTimeStamp) {
mCompositionTime = aTimeStamp;
if (!mCompositionTime.IsNull() && !mCompositeUntilTime.IsNull() &&
mCompositionTime >= mCompositeUntilTime) {
mCompositeUntilTime = TimeStamp();
}
}
void CompositeUntil(TimeStamp aTimeStamp) {
if (mCompositeUntilTime.IsNull() ||
mCompositeUntilTime < aTimeStamp) {
mCompositeUntilTime = aTimeStamp;
}
}
TimeStamp GetCompositeUntilTime() const {
return mCompositeUntilTime;
}
private:
struct ForwardingTextureHost {
@ -56,6 +76,14 @@ private:
};
nsClassHashtable<nsUint64HashKey, PipelineTexturesHolder> mPipelineTexturesHolders;
// Render time for the current composition.
TimeStamp mCompositionTime;
// When nonnull, during rendering, some compositable indicated that it will
// change its rendering at this time. In order not to miss it, we composite
// on every vsync until this time occurs (this is the latest such time).
TimeStamp mCompositeUntilTime;
};
} // namespace layers

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

@ -8,6 +8,7 @@
#include <inttypes.h>
#include "gfxPrefs.h"
#include "LayersLogging.h"
#include "mozilla/layers/StackingContextHelper.h"
#include "mozilla/layers/WebRenderBridgeChild.h"
#include "mozilla/webrender/WebRenderTypes.h"
@ -20,37 +21,44 @@ WebRenderContainerLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
nsTArray<LayerPolygon> children = SortChildrenBy3DZOrder(SortMode::WITHOUT_GEOMETRY);
gfx::Matrix4x4 transform = GetTransform();
gfx::Rect relBounds = GetWrRelBounds();
gfx::Rect overflow(0, 0, relBounds.width, relBounds.height);
gfx::Matrix4x4* maybeTransform = &transform;
float opacity = GetLocalOpacity();
float* maybeOpacity = &opacity;
uint64_t animationsId = 0;
if (gfxPrefs::WebRenderOMTAEnabled() &&
GetAnimations().Length()) {
MOZ_ASSERT(GetCompositorAnimationsId());
animationsId = GetCompositorAnimationsId();
CompositorAnimations anim;
anim.animations() = GetAnimations();
anim.id() = animationsId;
WrBridge()->AddWebRenderParentCommand(OpAddCompositorAnimations(anim));
if (!HasOpacityAnimation()) {
maybeOpacity = nullptr;
}
if (!HasTransformAnimation()) {
maybeTransform = nullptr;
}
}
StackingContextHelper sc(aBuilder, this, animationsId, maybeOpacity, maybeTransform);
LayerRect rect = Bounds();
DumpLayerInfo("ContainerLayer", rect);
Maybe<WrImageMask> mask = BuildWrMaskLayer(true);
aBuilder.PushClip(sc.ToRelativeWrRect(rect), mask.ptrOr(nullptr));
wr::MixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
if (gfxPrefs::LayersDump()) {
printf_stderr("ContainerLayer %p using bounds=%s, overflow=%s, transform=%s, mix-blend-mode=%s\n",
this->GetLayer(),
Stringify(relBounds).c_str(),
Stringify(overflow).c_str(),
Stringify(transform).c_str(),
Stringify(mixBlendMode).c_str());
}
aBuilder.PushStackingContext(wr::ToWrRect(relBounds),
GetLocalOpacity(),
//GetLayer()->GetAnimations(),
transform,
mixBlendMode);
aBuilder.PushScrollLayer(wr::ToWrRect(overflow),
wr::ToWrRect(overflow),
mask.ptrOr(nullptr));
for (LayerPolygon& child : children) {
if (child.layer->IsBackfaceHidden()) {
continue;
}
ToWebRenderLayer(child.layer)->RenderLayer(aBuilder);
}
aBuilder.PopScrollLayer();
aBuilder.PopStackingContext();
aBuilder.PopClip();
}
void

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

@ -6,8 +6,10 @@
#ifndef GFX_WEBRENDERCONTAINERLAYER_H
#define GFX_WEBRENDERCONTAINERLAYER_H
#include "gfxPrefs.h"
#include "Layers.h"
#include "WebRenderLayerManager.h"
#include "mozilla/layers/WebRenderLayer.h"
#include "mozilla/layers/WebRenderLayerManager.h"
namespace mozilla {
namespace layers {
@ -25,6 +27,13 @@ public:
protected:
virtual ~WebRenderContainerLayer()
{
if (gfxPrefs::WebRenderOMTAEnabled() &&
GetAnimations().Length()) {
mManager->AsWebRenderLayerManager()->
AddCompositorAnimationsIdForDiscard(GetCompositorAnimationsId());
}
ContainerLayer::RemoveAllChildren();
MOZ_COUNT_DTOR(WebRenderContainerLayer);
}

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

@ -11,10 +11,23 @@
#include "mozilla/layers/WebRenderBridgeChild.h"
#include "nsDisplayList.h"
#include "mozilla/gfx/Matrix.h"
#include "mozilla/layers/UpdateImageHelper.h"
#include "UnitTransforms.h"
namespace mozilla {
namespace layers {
WebRenderDisplayItemLayer::~WebRenderDisplayItemLayer()
{
MOZ_COUNT_DTOR(WebRenderDisplayItemLayer);
if (mKey.isSome()) {
WrManager()->AddImageKeyForDiscard(mKey.value());
}
if (mExternalImageId.isSome()) {
WrBridge()->DeallocExternalImageId(mExternalImageId.ref());
}
}
void
WebRenderDisplayItemLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
{
@ -26,10 +39,8 @@ WebRenderDisplayItemLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
WrImageMask* imageMask = mask.ptrOr(nullptr);
if (imageMask) {
gfx::Rect rect = TransformedVisibleBoundsRelativeToParent();
gfx::Rect overflow(0.0, 0.0, rect.width, rect.height);
aBuilder.PushScrollLayer(wr::ToWrRect(rect),
wr::ToWrRect(overflow),
imageMask);
gfx::Rect clip(0.0, 0.0, rect.width, rect.height);
aBuilder.PushClip(wr::ToWrRect(clip), imageMask);
}
if (mItem) {
@ -38,15 +49,25 @@ WebRenderDisplayItemLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
mParentCommands.Clear();
mItem->CreateWebRenderCommands(builder, mParentCommands, this);
mBuiltDisplayList = builder.Finalize();
} else {
// else we have an empty transaction and just use the
// old commands.
WebRenderLayerManager* manager = static_cast<WebRenderLayerManager*>(Manager());
MOZ_ASSERT(manager);
// Since our recording relies on our parent layer's transform and stacking context
// If this layer or our parent changed, this empty transaction won't work.
if (manager->IsMutatedLayer(this) || manager->IsMutatedLayer(GetParent())) {
manager->SetTransactionIncomplete();
return;
}
}
// else we have an empty transaction and just use the
// old commands.
aBuilder.PushBuiltDisplayList(Move(mBuiltDisplayList));
WrBridge()->AddWebRenderParentCommands(mParentCommands);
if (imageMask) {
aBuilder.PopScrollLayer();
aBuilder.PopClip();
}
}
@ -54,6 +75,8 @@ Maybe<wr::ImageKey>
WebRenderDisplayItemLayer::SendImageContainer(ImageContainer* aContainer,
nsTArray<layers::WebRenderParentCommand>& aParentCommands)
{
MOZ_ASSERT(aContainer);
if (mImageContainer != aContainer) {
AutoLockImage autoLock(aContainer);
Image* image = autoLock.GetImage();
@ -71,26 +94,92 @@ WebRenderDisplayItemLayer::SendImageContainer(ImageContainer* aContainer,
mImageClient->Connect();
}
if (!mExternalImageId) {
if (mExternalImageId.isNothing()) {
MOZ_ASSERT(mImageClient);
mExternalImageId = WrBridge()->AllocExternalImageIdForCompositable(mImageClient);
mExternalImageId = Some(WrBridge()->AllocExternalImageIdForCompositable(mImageClient));
}
MOZ_ASSERT(mExternalImageId);
MOZ_ASSERT(mExternalImageId.isSome());
MOZ_ASSERT(mImageClient->AsImageClientSingle());
mKey = UpdateImageKey(mImageClient->AsImageClientSingle(),
aContainer,
mKey,
mExternalImageId.ref());
if (!mImageClient->UpdateImage(aContainer, /* unused */0)) {
return Nothing();
}
mImageContainer = aContainer;
}
WrImageKey key;
key.mNamespace = WrBridge()->GetNamespace();
key.mHandle = WrBridge()->GetNextResourceId();
return mKey;
}
bool
WebRenderDisplayItemLayer::PushItemAsImage(wr::DisplayListBuilder& aBuilder,
nsTArray<layers::WebRenderParentCommand>& aParentCommands)
{
if (!mImageContainer) {
mImageContainer = LayerManager::CreateImageContainer();
}
if (!mImageClient) {
mImageClient = ImageClient::CreateImageClient(CompositableType::IMAGE,
WrBridge(),
TextureFlags::DEFAULT);
if (!mImageClient) {
return false;
}
mImageClient->Connect();
}
if (mExternalImageId.isNothing()) {
MOZ_ASSERT(mImageClient);
mExternalImageId = Some(WrBridge()->AllocExternalImageIdForCompositable(mImageClient));
}
const int32_t appUnitsPerDevPixel = mItem->Frame()->PresContext()->AppUnitsPerDevPixel();
bool snap;
LayerRect bounds = ViewAs<LayerPixel>(
LayoutDeviceRect::FromAppUnits(mItem->GetBounds(mBuilder, &snap), appUnitsPerDevPixel),
PixelCastJustification::WebRenderHasUnitResolution);
LayerIntSize imageSize = RoundedToInt(bounds.Size());
LayerRect imageRect;
imageRect.SizeTo(LayerSize(imageSize));
UpdateImageHelper helper(mImageContainer, mImageClient, imageSize.ToUnknownSize());
LayerPoint offset = ViewAs<LayerPixel>(
LayoutDevicePoint::FromAppUnits(mItem->ToReferenceFrame(), appUnitsPerDevPixel),
PixelCastJustification::WebRenderHasUnitResolution);
{
RefPtr<gfx::DrawTarget> target = helper.GetDrawTarget();
if (!target) {
return false;
}
target->ClearRect(imageRect.ToUnknownRect());
RefPtr<gfxContext> context = gfxContext::CreateOrNull(target, offset.ToUnknownPoint());
MOZ_ASSERT(context);
nsRenderingContext ctx(context);
mItem->Paint(mBuilder, &ctx);
}
if (!helper.UpdateImage()) {
return false;
}
LayerRect dest = RelativeToParent(imageRect) + offset;
WrClipRegion clipRegion = aBuilder.BuildClipRegion(wr::ToWrRect(dest));
WrImageKey key = GetImageKey();
aParentCommands.AppendElement(layers::OpAddExternalImage(
mExternalImageId,
mExternalImageId.value(),
key));
WrManager()->AddImageKeyForDiscard(key);
return Some(key);
aBuilder.PushImage(wr::ToWrRect(dest),
clipRegion,
WrImageRendering::Auto,
key);
return true;
}
} // namespace layers

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

@ -9,9 +9,10 @@
#include "Layers.h"
#include "mozilla/layers/ImageClient.h"
#include "mozilla/layers/PWebRenderBridgeChild.h"
#include "mozilla/layers/WebRenderLayer.h"
#include "mozilla/layers/WebRenderLayerManager.h"
#include "mozilla/Maybe.h"
#include "mozilla/webrender/WebRenderTypes.h"
#include "WebRenderLayerManager.h"
namespace mozilla {
namespace layers {
@ -21,19 +22,17 @@ class WebRenderDisplayItemLayer : public WebRenderLayer,
public:
explicit WebRenderDisplayItemLayer(WebRenderLayerManager* aLayerManager)
: DisplayItemLayer(aLayerManager, static_cast<WebRenderLayer*>(this))
, mExternalImageId(0)
{
MOZ_COUNT_CTOR(WebRenderDisplayItemLayer);
}
Maybe<wr::ImageKey> SendImageContainer(ImageContainer* aContainer,
nsTArray<layers::WebRenderParentCommand>& aParentCommands);
bool PushItemAsImage(wr::DisplayListBuilder& aBuilder,
nsTArray<layers::WebRenderParentCommand>& aParentCommands);
protected:
virtual ~WebRenderDisplayItemLayer()
{
MOZ_COUNT_DTOR(WebRenderDisplayItemLayer);
}
virtual ~WebRenderDisplayItemLayer();
public:
Layer* GetLayer() override { return this; }
@ -44,8 +43,8 @@ private:
nsTArray<WebRenderParentCommand> mParentCommands;
RefPtr<ImageClient> mImageClient;
RefPtr<ImageContainer> mImageContainer;
uint64_t mExternalImageId;
wr::MaybeExternalImageId mExternalImageId;
Maybe<wr::ImageKey> mKey;
};
} // namespace layers

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

@ -9,6 +9,7 @@
#include "mozilla/layers/Compositor.h" // for Compositor
#include "mozilla/layers/Effects.h" // for TexturedEffect, Effect, etc
#include "mozilla/layers/LayerManagerComposite.h" // for TexturedEffect, Effect, etc
#include "mozilla/layers/WebRenderCompositableHolder.h"
#include "nsAString.h"
#include "nsDebug.h" // for NS_WARNING, NS_ASSERTION
#include "nsPrintfCString.h" // for nsPrintfCString
@ -25,10 +26,12 @@ class ISurfaceAllocator;
WebRenderImageHost::WebRenderImageHost(const TextureInfo& aTextureInfo)
: CompositableHost(aTextureInfo)
, ImageComposite()
, mWrCompositableHolder(nullptr)
{}
WebRenderImageHost::~WebRenderImageHost()
{
MOZ_ASSERT(!mWrCompositableHolder);
}
void
@ -62,6 +65,22 @@ WebRenderImageHost::UseTextureHost(const nsTArray<TimedTexture>& aTextures)
mImages.SwapElements(newImages);
newImages.Clear();
// Video producers generally send replacement images with the same frameID but
// slightly different timestamps in order to sync with the audio clock. This
// means that any CompositeUntil() call we made in Composite() may no longer
// guarantee that we'll composite until the next frame is ready. Fix that here.
if (mWrCompositableHolder && mLastFrameID >= 0) {
for (size_t i = 0; i < mImages.Length(); ++i) {
bool frameComesAfter = mImages[i].mFrameID > mLastFrameID ||
mImages[i].mProducerID != mLastProducerID;
if (frameComesAfter && !mImages[i].mTimeStamp.IsNull()) {
mWrCompositableHolder->CompositeUntil(mImages[i].mTimeStamp +
TimeDuration::FromMilliseconds(BIAS_TIME_MS));
break;
}
}
}
}
void
@ -95,8 +114,11 @@ WebRenderImageHost::RemoveTextureHost(TextureHost* aTexture)
TimeStamp
WebRenderImageHost::GetCompositionTime() const
{
// XXX temporary workaround
return TimeStamp::Now();
TimeStamp time;
if (mWrCompositableHolder) {
time = mWrCompositableHolder->GetCompositionTime();
}
return time;
}
TextureHost*
@ -109,6 +131,27 @@ WebRenderImageHost::GetAsTextureHost(IntRect* aPictureRect)
return nullptr;
}
TextureHost*
WebRenderImageHost::GetAsTextureHostForComposite()
{
int imageIndex = ChooseImageIndex();
if (imageIndex < 0) {
return nullptr;
}
if (mWrCompositableHolder && uint32_t(imageIndex) + 1 < mImages.Length()) {
mWrCompositableHolder->CompositeUntil(mImages[imageIndex + 1].mTimeStamp + TimeDuration::FromMilliseconds(BIAS_TIME_MS));
}
TimedImage* img = &mImages[imageIndex];
if (mLastFrameID != img->mFrameID || mLastProducerID != img->mProducerID) {
mLastFrameID = img->mFrameID;
mLastProducerID = img->mProducerID;
}
return img->mTextureHost;
}
void WebRenderImageHost::Attach(Layer* aLayer,
TextureSourceProvider* aProvider,
AttachFlags aFlags)

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

@ -12,6 +12,8 @@
namespace mozilla {
namespace layers {
class WebRenderCompositableHolder;
/**
* ImageHost. Works with ImageClientSingle and ImageClientBuffered
*/
@ -65,9 +67,18 @@ public:
virtual WebRenderImageHost* AsWebRenderImageHost() override { return this; }
TextureHost* GetAsTextureHostForComposite();
void SetWrCompositableHolder(WebRenderCompositableHolder* aWrCompositableHolder)
{
mWrCompositableHolder = aWrCompositableHolder;
}
protected:
// ImageComposite
virtual TimeStamp GetCompositionTime() const override;
WebRenderCompositableHolder* MOZ_NON_OWNING_REF mWrCompositableHolder;
};
} // namespace layers

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

@ -8,6 +8,7 @@
#include "gfxPrefs.h"
#include "LayersLogging.h"
#include "mozilla/layers/ImageClient.h"
#include "mozilla/layers/StackingContextHelper.h"
#include "mozilla/layers/TextureClientRecycleAllocator.h"
#include "mozilla/layers/TextureWrapperImage.h"
#include "mozilla/layers/WebRenderBridgeChild.h"
@ -20,7 +21,6 @@ using namespace gfx;
WebRenderImageLayer::WebRenderImageLayer(WebRenderLayerManager* aLayerManager)
: ImageLayer(aLayerManager, static_cast<WebRenderLayer*>(this))
, mExternalImageId(0)
, mImageClientTypeContainer(CompositableType::UNKNOWN)
{
MOZ_COUNT_CTOR(WebRenderImageLayer);
@ -29,8 +29,12 @@ WebRenderImageLayer::WebRenderImageLayer(WebRenderLayerManager* aLayerManager)
WebRenderImageLayer::~WebRenderImageLayer()
{
MOZ_COUNT_DTOR(WebRenderImageLayer);
if (mExternalImageId) {
WrBridge()->DeallocExternalImageId(mExternalImageId);
mPipelineIdRequest.DisconnectIfExists();
if (mKey.isSome()) {
WrManager()->AddImageKeyForDiscard(mKey.value());
}
if (mExternalImageId.isSome()) {
WrBridge()->DeallocExternalImageId(mExternalImageId.ref());
}
}
@ -93,6 +97,24 @@ WebRenderImageLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
MOZ_ASSERT(GetImageClientType() != CompositableType::UNKNOWN);
// Allocate PipelineId if necessary
if (GetImageClientType() == CompositableType::IMAGE_BRIDGE &&
mPipelineId.isNothing() && !mPipelineIdRequest.Exists()) {
// Use Holder to pass this pointer to lambda.
// Static anaysis tool does not permit to pass refcounted variable to lambda.
// And we do not want to use RefPtr<WebRenderImageLayer> here.
Holder holder(this);
Manager()->AllocPipelineId()
->Then(AbstractThread::GetCurrent(), __func__,
[holder] (const wr::PipelineId& aPipelineId) {
holder->mPipelineIdRequest.Complete();
holder->mPipelineId = Some(aPipelineId);
},
[holder] (const ipc::PromiseRejectReason &aReason) {
holder->mPipelineIdRequest.Complete();
})->Track(mPipelineIdRequest);
}
if (GetImageClientType() == CompositableType::IMAGE && !mImageClient) {
mImageClient = ImageClient::CreateImageClient(CompositableType::IMAGE,
WrBridge(),
@ -103,17 +125,17 @@ WebRenderImageLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
mImageClient->Connect();
}
if (!mExternalImageId) {
if (mExternalImageId.isNothing()) {
if (GetImageClientType() == CompositableType::IMAGE_BRIDGE) {
MOZ_ASSERT(!mImageClient);
mExternalImageId = WrBridge()->AllocExternalImageId(mContainer->GetAsyncContainerHandle());
mExternalImageId = Some(WrBridge()->AllocExternalImageId(mContainer->GetAsyncContainerHandle()));
} else {
// Handle CompositableType::IMAGE case
MOZ_ASSERT(mImageClient);
mExternalImageId = WrBridge()->AllocExternalImageIdForCompositable(mImageClient);
mExternalImageId = Some(WrBridge()->AllocExternalImageIdForCompositable(mImageClient));
}
}
MOZ_ASSERT(mExternalImageId);
MOZ_ASSERT(mExternalImageId.isSome());
// XXX Not good for async ImageContainer case.
AutoLockImage autoLock(mContainer);
@ -123,27 +145,41 @@ WebRenderImageLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
}
gfx::IntSize size = image->GetSize();
if (mImageClient && !mImageClient->UpdateImage(mContainer, /* unused */0)) {
if (GetImageClientType() == CompositableType::IMAGE_BRIDGE) {
// Always allocate key
WrImageKey key = GetImageKey();
WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId.value(), key));
Manager()->AddImageKeyForDiscard(key);
mKey = Some(key);
} else {
// Handle CompositableType::IMAGE case
MOZ_ASSERT(mImageClient->AsImageClientSingle());
mKey = UpdateImageKey(mImageClient->AsImageClientSingle(),
mContainer,
mKey,
mExternalImageId.ref());
}
if (mKey.isNothing()) {
return;
}
gfx::Matrix4x4 transform = GetTransform();
gfx::Rect relBounds = GetWrRelBounds();
StackingContextHelper sc(aBuilder, this);
gfx::Rect rect = gfx::Rect(0, 0, size.width, size.height);
LayerRect rect(0, 0, size.width, size.height);
if (mScaleMode != ScaleMode::SCALE_NONE) {
NS_ASSERTION(mScaleMode == ScaleMode::STRETCH,
"No other scalemodes than stretch and none supported yet.");
rect = gfx::Rect(0, 0, mScaleToSize.width, mScaleToSize.height);
rect = LayerRect(0, 0, mScaleToSize.width, mScaleToSize.height);
}
rect = RelativeToVisible(rect);
gfx::Rect clipRect = GetWrClipRect(rect);
LayerRect clipRect = ClipRect().valueOr(rect);
Maybe<WrImageMask> mask = BuildWrMaskLayer(true);
WrClipRegion clip = aBuilder.BuildClipRegion(wr::ToWrRect(clipRect), mask.ptrOr(nullptr));
WrClipRegion clip = aBuilder.BuildClipRegion(
sc.ToRelativeWrRect(clipRect),
mask.ptrOr(nullptr));
wr::ImageRendering filter = wr::ToImageRendering(mSamplingFilter);
wr::MixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
DumpLayerInfo("Image Layer", rect);
if (gfxPrefs::LayersDump()) {
@ -152,19 +188,7 @@ WebRenderImageLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
Stringify(filter).c_str());
}
WrImageKey key;
key.mNamespace = WrBridge()->GetNamespace();
key.mHandle = WrBridge()->GetNextResourceId();
WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId, key));
Manager()->AddImageKeyForDiscard(key);
aBuilder.PushStackingContext(wr::ToWrRect(relBounds),
1.0f,
//GetAnimations(),
transform,
mixBlendMode);
aBuilder.PushImage(wr::ToWrRect(rect), clip, filter, key);
aBuilder.PopStackingContext();
aBuilder.PushImage(sc.ToRelativeWrRect(rect), clip, filter, mKey.value());
}
Maybe<WrImageMask>
@ -194,29 +218,28 @@ WebRenderImageLayer::RenderMaskLayer(const gfx::Matrix4x4& aTransform)
mImageClient->Connect();
}
if (!mExternalImageId) {
mExternalImageId = WrBridge()->AllocExternalImageIdForCompositable(mImageClient);
if (mExternalImageId.isNothing()) {
mExternalImageId = Some(WrBridge()->AllocExternalImageIdForCompositable(mImageClient));
}
MOZ_ASSERT(mExternalImageId);
AutoLockImage autoLock(mContainer);
Image* image = autoLock.GetImage();
if (!image) {
return Nothing();
}
if (!mImageClient->UpdateImage(mContainer, /* unused */0)) {
MOZ_ASSERT(mImageClient->AsImageClientSingle());
mKey = UpdateImageKey(mImageClient->AsImageClientSingle(),
mContainer,
mKey,
mExternalImageId.ref());
if (mKey.isNothing()) {
return Nothing();
}
WrImageKey key;
key.mNamespace = WrBridge()->GetNamespace();
key.mHandle = WrBridge()->GetNextResourceId();
WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId, key));
Manager()->AddImageKeyForDiscard(key);
gfx::IntSize size = image->GetSize();
WrImageMask imageMask;
imageMask.image = key;
imageMask.image = mKey.value();
Rect maskRect = aTransform.TransformBounds(Rect(0, 0, size.width, size.height));
imageMask.rect = wr::ToWrRect(maskRect);
imageMask.repeat = false;

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

@ -7,7 +7,8 @@
#define GFX_WEBRENDERIMAGELAYER_H
#include "ImageLayers.h"
#include "WebRenderLayerManager.h"
#include "mozilla/layers/WebRenderLayer.h"
#include "mozilla/layers/WebRenderLayerManager.h"
namespace mozilla {
namespace layers {
@ -22,6 +23,7 @@ public:
virtual already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override;
virtual void ClearCachedResources() override;
protected:
virtual ~WebRenderImageLayer();
@ -38,9 +40,22 @@ public:
protected:
CompositableType GetImageClientType();
uint64_t mExternalImageId;
class Holder {
public:
explicit Holder(WebRenderImageLayer* aLayer)
: mLayer(aLayer)
{}
WebRenderImageLayer* operator ->() const { return mLayer; }
private:
WebRenderImageLayer* mLayer;
};
wr::MaybeExternalImageId mExternalImageId;
Maybe<wr::ImageKey> mKey;
RefPtr<ImageClient> mImageClient;
CompositableType mImageClientTypeContainer;
Maybe<wr::PipelineId> mPipelineId;
MozPromiseRequestHolder<PipelineIdPromise> mPipelineIdRequest;
};
} // namespace layers

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

@ -0,0 +1,201 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebRenderLayer.h"
#include "gfxPrefs.h"
#include "LayersLogging.h"
#include "mozilla/layers/ImageClient.h"
#include "mozilla/layers/WebRenderBridgeChild.h"
#include "mozilla/layers/WebRenderLayerManager.h"
#include "nsThreadUtils.h"
#include "UnitTransforms.h"
namespace mozilla {
using namespace gfx;
namespace layers {
WebRenderLayerManager*
WebRenderLayer::WrManager()
{
return static_cast<WebRenderLayerManager*>(GetLayer()->Manager());
}
WebRenderBridgeChild*
WebRenderLayer::WrBridge()
{
return WrManager()->WrBridge();
}
WrImageKey
WebRenderLayer::GetImageKey()
{
WrImageKey key;
key.mNamespace = WrBridge()->GetNamespace();
key.mHandle = WrBridge()->GetNextResourceId();
return key;
}
LayerRect
WebRenderLayer::ParentBounds()
{
// Walk up to find the parent stacking context. This will be created by the
// parent layer which must be a ContainerLayer if it exists.
if (Layer* parent = GetLayer()->GetParent()) {
return ToWebRenderLayer(parent)->Bounds();
}
return LayerRect();
}
LayerRect
WebRenderLayer::RelativeToParent(const LayerRect& aRect)
{
return aRect - ParentBounds().TopLeft();
}
LayerRect
WebRenderLayer::RelativeToParent(const LayoutDeviceRect& aRect)
{
return RelativeToParent(ViewAs<LayerPixel>(
aRect, PixelCastJustification::WebRenderHasUnitResolution));
}
LayerPoint
WebRenderLayer::GetOffsetToParent()
{
return ParentBounds().TopLeft();
}
gfx::Rect
WebRenderLayer::TransformedVisibleBoundsRelativeToParent()
{
IntRect bounds = GetLayer()->GetVisibleRegion().GetBounds().ToUnknownRect();
Rect transformed = GetLayer()->GetTransform().TransformBounds(IntRectToRect(bounds));
return transformed - ParentBounds().ToUnknownRect().TopLeft();
}
Maybe<WrImageMask>
WebRenderLayer::BuildWrMaskLayer(bool aUnapplyLayerTransform)
{
if (GetLayer()->GetMaskLayer()) {
WebRenderLayer* maskLayer = ToWebRenderLayer(GetLayer()->GetMaskLayer());
// The size of mask layer is transformed, and we may set the layer transform
// to wr stacking context. So we should apply inverse transform for mask layer
// and reverse the offset of the stacking context.
gfx::Matrix4x4 transform = maskLayer->GetLayer()->GetTransform();
if (aUnapplyLayerTransform) {
gfx::Rect bounds = IntRectToRect(GetLayer()->GetVisibleRegion().GetBounds().ToUnknownRect());
transform = transform.PreTranslate(-bounds.x, -bounds.y, 0);
transform = transform * GetLayer()->GetTransform().Inverse();
}
return maskLayer->RenderMaskLayer(transform);
}
return Nothing();
}
LayerRect
WebRenderLayer::Bounds()
{
return LayerRect(GetLayer()->GetVisibleRegion().GetBounds());
}
BoundsTransformMatrix
WebRenderLayer::BoundsTransform()
{
gfx::Matrix4x4 transform = GetLayer()->GetTransform();
transform._41 = 0.0f;
transform._42 = 0.0f;
transform._43 = 0.0f;
return ViewAs<BoundsTransformMatrix>(transform);
}
LayerRect
WebRenderLayer::BoundsForStackingContext()
{
LayerRect bounds = Bounds();
BoundsTransformMatrix transform = BoundsTransform();
if (!transform.IsIdentity()) {
// WR will only apply the 'translate' of the transform, so we need to do the scale/rotation manually.
bounds.MoveTo(transform.TransformPoint(bounds.TopLeft()));
}
return bounds;
}
Maybe<LayerRect>
WebRenderLayer::ClipRect()
{
Layer* layer = GetLayer();
if (!layer->GetClipRect()) {
return Nothing();
}
ParentLayerRect clip(layer->GetClipRect().ref());
LayerToParentLayerMatrix4x4 transform = layer->GetLocalTransformTyped();
return Some(transform.Inverse().TransformBounds(clip));
}
Maybe<wr::ImageKey>
WebRenderLayer::UpdateImageKey(ImageClientSingle* aImageClient,
ImageContainer* aContainer,
Maybe<wr::ImageKey>& aOldKey,
wr::ExternalImageId& aExternalImageId)
{
MOZ_ASSERT(aImageClient);
MOZ_ASSERT(aContainer);
uint32_t oldCounter = aImageClient->GetLastUpdateGenerationCounter();
bool ret = aImageClient->UpdateImage(aContainer, /* unused */0);
if (!ret || aImageClient->IsEmpty()) {
// Delete old key
if (aOldKey.isSome()) {
WrManager()->AddImageKeyForDiscard(aOldKey.value());
}
return Nothing();
}
// Reuse old key if generation is not updated.
if (oldCounter == aImageClient->GetLastUpdateGenerationCounter() && aOldKey.isSome()) {
return aOldKey;
}
// Delete old key, we are generating a new key.
if (aOldKey.isSome()) {
WrManager()->AddImageKeyForDiscard(aOldKey.value());
}
WrImageKey key = GetImageKey();
WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(aExternalImageId, key));
return Some(key);
}
void
WebRenderLayer::DumpLayerInfo(const char* aLayerType, const LayerRect& aRect)
{
if (!gfxPrefs::LayersDump()) {
return;
}
Matrix4x4 transform = GetLayer()->GetTransform();
LayerRect bounds = Bounds();
WrMixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetLayer()->GetMixBlendMode());
printf_stderr("%s %p using bounds=%s, transform=%s, rect=%s, clip=%s, mix-blend-mode=%s\n",
aLayerType,
GetLayer(),
Stringify(bounds).c_str(),
Stringify(transform).c_str(),
Stringify(aRect).c_str(),
Stringify(ClipRect().valueOr(aRect)).c_str(),
Stringify(mixBlendMode).c_str());
}
} // namespace layers
} // namespace mozilla

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

@ -0,0 +1,69 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GFX_WEBRENDERLAYER_H
#define GFX_WEBRENDERLAYER_H
#include "Layers.h"
#include "mozilla/webrender/WebRenderTypes.h"
#include "mozilla/webrender/WebRenderAPI.h"
namespace mozilla {
namespace layers {
class ImageClientSingle;
class WebRenderBridgeChild;
class WebRenderLayerManager;
typedef gfx::Matrix4x4Typed<LayerPixel, LayerPixel> BoundsTransformMatrix;
class WebRenderLayer
{
public:
virtual Layer* GetLayer() = 0;
virtual void RenderLayer(wr::DisplayListBuilder& aBuilder) = 0;
virtual Maybe<WrImageMask> RenderMaskLayer(const gfx::Matrix4x4& aTransform)
{
MOZ_ASSERT(false);
return Nothing();
}
virtual already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() { return nullptr; }
static inline WebRenderLayer*
ToWebRenderLayer(Layer* aLayer)
{
return static_cast<WebRenderLayer*>(aLayer->ImplData());
}
Maybe<wr::ImageKey> UpdateImageKey(ImageClientSingle* aImageClient,
ImageContainer* aContainer,
Maybe<wr::ImageKey>& aOldKey,
wr::ExternalImageId& aExternalImageId);
WebRenderLayerManager* WrManager();
WebRenderBridgeChild* WrBridge();
WrImageKey GetImageKey();
LayerRect RelativeToParent(const LayerRect& aRect);
LayerRect RelativeToParent(const LayoutDeviceRect& aRect);
LayerPoint GetOffsetToParent();
LayerRect Bounds();
LayerRect BoundsForStackingContext();
protected:
BoundsTransformMatrix BoundsTransform();
LayerRect ParentBounds();
Maybe<LayerRect> ClipRect();
gfx::Rect TransformedVisibleBoundsRelativeToParent();
void DumpLayerInfo(const char* aLayerType, const LayerRect& aRect);
Maybe<WrImageMask> BuildWrMaskLayer(bool aUnapplyLayerTransform);
};
} // namespace layers
} // namespace mozilla
#endif /* GFX_WEBRENDERLAYER_H */

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

@ -5,18 +5,13 @@
#include "WebRenderLayerManager.h"
#include "apz/src/AsyncPanZoomController.h"
#include "gfxPrefs.h"
#include "LayersLogging.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/layers/APZCTreeManager.h"
#include "mozilla/layers/AsyncCompositionManager.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/gfx/GPUProcessManager.h"
#include "mozilla/layers/CompositorBridgeChild.h"
#include "mozilla/layers/TextureClient.h"
#include "mozilla/layers/WebRenderBridgeChild.h"
#include "mozilla/widget/PlatformWidgetTypes.h"
#include "nsThreadUtils.h"
#include "TreeTraversal.h"
#include "WebRenderCanvasLayer.h"
#include "WebRenderColorLayer.h"
#include "WebRenderContainerLayer.h"
@ -31,169 +26,11 @@ using namespace gfx;
namespace layers {
WebRenderLayerManager*
WebRenderLayer::WrManager()
{
return static_cast<WebRenderLayerManager*>(GetLayer()->Manager());
}
WebRenderBridgeChild*
WebRenderLayer::WrBridge()
{
return WrManager()->WrBridge();
}
Rect
WebRenderLayer::RelativeToVisible(Rect aRect)
{
IntRect bounds = GetLayer()->GetVisibleRegion().GetBounds().ToUnknownRect();
aRect.MoveBy(-bounds.x, -bounds.y);
return aRect;
}
Rect
WebRenderLayer::RelativeToTransformedVisible(Rect aRect)
{
IntRect bounds = GetLayer()->GetVisibleRegion().GetBounds().ToUnknownRect();
Rect transformed = GetLayer()->GetTransform().TransformBounds(IntRectToRect(bounds));
aRect.MoveBy(-transformed.x, -transformed.y);
return aRect;
}
Rect
WebRenderLayer::ParentStackingContextBounds()
{
// Walk up to find the parent stacking context. This will be created either
// by the nearest scrollable metrics, or by the parent layer which must be a
// ContainerLayer.
Layer* layer = GetLayer();
if (layer->GetParent()) {
return IntRectToRect(layer->GetParent()->GetVisibleRegion().GetBounds().ToUnknownRect());
}
return Rect();
}
Rect
WebRenderLayer::RelativeToParent(Rect aRect)
{
Rect parentBounds = ParentStackingContextBounds();
aRect.MoveBy(-parentBounds.x, -parentBounds.y);
return aRect;
}
Point
WebRenderLayer::GetOffsetToParent()
{
Rect parentBounds = ParentStackingContextBounds();
return parentBounds.TopLeft();
}
Rect
WebRenderLayer::VisibleBoundsRelativeToParent()
{
return RelativeToParent(IntRectToRect(GetLayer()->GetVisibleRegion().GetBounds().ToUnknownRect()));
}
Rect
WebRenderLayer::TransformedVisibleBoundsRelativeToParent()
{
IntRect bounds = GetLayer()->GetVisibleRegion().GetBounds().ToUnknownRect();
Rect transformed = GetLayer()->GetTransform().TransformBounds(IntRectToRect(bounds));
return RelativeToParent(transformed);
}
Maybe<WrImageMask>
WebRenderLayer::BuildWrMaskLayer(bool aUnapplyLayerTransform)
{
if (GetLayer()->GetMaskLayer()) {
WebRenderLayer* maskLayer = ToWebRenderLayer(GetLayer()->GetMaskLayer());
// The size of mask layer is transformed, and we may set the layer transform to wr stacking context.
// So we should apply inverse transform for mask layer.
gfx::Matrix4x4 transform;
if (aUnapplyLayerTransform) {
transform = GetWrBoundTransform().Inverse();
}
return maskLayer->RenderMaskLayer(transform);
}
return Nothing();
}
gfx::Rect
WebRenderLayer::GetWrBoundsRect()
{
LayerIntRect bounds = GetLayer()->GetVisibleRegion().GetBounds();
return Rect(0, 0, bounds.width, bounds.height);
}
gfx::Rect
WebRenderLayer::GetWrClipRect(gfx::Rect& aRect)
{
gfx::Rect clip;
Layer* layer = GetLayer();
Matrix4x4 transform = layer->GetTransform();
if (layer->GetClipRect().isSome()) {
clip = RelativeToVisible(transform.Inverse().TransformBounds(
IntRectToRect(layer->GetClipRect().ref().ToUnknownRect()))
);
} else {
clip = aRect;
}
return clip;
}
gfx::Matrix4x4
WebRenderLayer::GetWrBoundTransform()
{
gfx::Matrix4x4 transform = GetLayer()->GetTransform();
transform._41 = 0.0f;
transform._42 = 0.0f;
transform._43 = 0.0f;
return transform;
}
gfx::Rect
WebRenderLayer::GetWrRelBounds()
{
gfx::Rect bounds = IntRectToRect(GetLayer()->GetVisibleRegion().GetBounds().ToUnknownRect());
gfx::Matrix4x4 transform = GetWrBoundTransform();
if (!transform.IsIdentity()) {
// WR will only apply the 'translate' of the transform, so we need to do the scale/rotation manually.
bounds.MoveTo(transform.TransformPoint(bounds.TopLeft()));
}
return RelativeToParent(bounds);
}
void
WebRenderLayer::DumpLayerInfo(const char* aLayerType, gfx::Rect& aRect)
{
if (!gfxPrefs::LayersDump()) {
return;
}
Matrix4x4 transform = GetLayer()->GetTransform();
Rect clip = GetWrClipRect(aRect);
Rect relBounds = GetWrRelBounds();
Rect overflow(0, 0, relBounds.width, relBounds.height);
WrMixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetLayer()->GetMixBlendMode());
printf_stderr("%s %p using bounds=%s, overflow=%s, transform=%s, rect=%s, clip=%s, mix-blend-mode=%s\n",
aLayerType,
GetLayer(),
Stringify(relBounds).c_str(),
Stringify(overflow).c_str(),
Stringify(transform).c_str(),
Stringify(aRect).c_str(),
Stringify(clip).c_str(),
Stringify(mixBlendMode).c_str());
}
WebRenderLayerManager::WebRenderLayerManager(nsIWidget* aWidget)
: mWidget(aWidget)
, mLatestTransactionId(0)
, mNeedsComposite(false)
, mIsFirstPaint(false)
, mTarget(nullptr)
{
MOZ_COUNT_CTOR(WebRenderLayerManager);
@ -246,11 +83,16 @@ WebRenderLayerManager::Destroy()
RefPtr<TransactionIdAllocator> allocator = mTransactionIdAllocator;
uint64_t id = mLatestTransactionId;
RefPtr<Runnable> task = NS_NewRunnableFunction([allocator, id] () -> void {
RefPtr<Runnable> task = NS_NewRunnableFunction(
"TransactionIdAllocator::NotifyTransactionCompleted",
[allocator, id] () -> void {
allocator->NotifyTransactionCompleted(id);
});
NS_DispatchToMainThread(task.forget());
}
// Forget the widget pointer in case we outlive our owning widget.
mWidget = nullptr;
}
WebRenderLayerManager::~WebRenderLayerManager()
@ -287,7 +129,30 @@ WebRenderLayerManager::BeginTransaction()
bool
WebRenderLayerManager::EndEmptyTransaction(EndTransactionFlags aFlags)
{
return false;
if (!mRoot) {
return false;
}
// We might used painted layer images so don't delete them yet.
return EndTransactionInternal(nullptr, nullptr, aFlags);
}
/*static*/ int32_t
PopulateScrollData(WebRenderScrollData& aTarget, Layer* aLayer)
{
MOZ_ASSERT(aLayer);
// We want to allocate a WebRenderLayerScrollData object for this layer,
// but don't keep a pointer to it since it might get memmove'd during the
// recursion below. Instead keep the index and get the pointer later.
size_t index = aTarget.AddNewLayerData();
int32_t descendants = 0;
for (Layer* child = aLayer->GetLastChild(); child; child = child->GetPrevSibling()) {
descendants += PopulateScrollData(aTarget, child);
}
aTarget.GetLayerDataMutable(index)->Initialize(aTarget, aLayer, descendants);
return descendants + 1;
}
void
@ -297,9 +162,17 @@ WebRenderLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback,
{
DiscardImages();
WrBridge()->RemoveExpiredFontKeys();
EndTransactionInternal(aCallback, aCallbackData, aFlags);
}
bool
WebRenderLayerManager::EndTransactionInternal(DrawPaintedLayerCallback aCallback,
void* aCallbackData,
EndTransactionFlags aFlags)
{
mPaintedLayerCallback = aCallback;
mPaintedLayerCallbackData = aCallbackData;
mTransactionIncomplete = false;
if (gfxPrefs::LayersDump()) {
this->Dump();
@ -310,16 +183,38 @@ WebRenderLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback,
LayoutDeviceIntSize size = mWidget->GetClientSize();
if (!WrBridge()->DPBegin(size.ToUnknownSize())) {
return;
return false;
}
DiscardCompositorAnimations();
mRoot->StartPendingAnimations(mAnimationReadyTime);
wr::DisplayListBuilder builder(WrBridge()->GetPipeline());
WebRenderLayer::ToWebRenderLayer(mRoot)->RenderLayer(builder);
WrBridge()->ClearReadLocks();
// We can't finish this transaction so return. This usually
// happens in an empty transaction where we can't repaint a painted layer.
// In this case, leave the transaction open and let a full transaction happen.
if (mTransactionIncomplete) {
DiscardLocalImages();
return false;
}
WebRenderScrollData scrollData;
if (mWidget->AsyncPanZoomEnabled()) {
if (mIsFirstPaint) {
scrollData.SetIsFirstPaint();
mIsFirstPaint = false;
}
if (mRoot) {
PopulateScrollData(scrollData, mRoot.get());
}
}
bool sync = mTarget != nullptr;
mLatestTransactionId = mTransactionIdAllocator->GetTransactionId();
WrBridge()->DPEnd(builder, size.ToUnknownSize(), sync, mLatestTransactionId);
WrBridge()->DPEnd(builder, size.ToUnknownSize(), sync, mLatestTransactionId, scrollData);
MakeSnapshotIfRequired(size);
mNeedsComposite = false;
@ -329,6 +224,9 @@ WebRenderLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback,
// this may result in Layers being deleted, which results in
// PLayer::Send__delete__() and DeallocShmem()
mKeepAlive.Clear();
ClearMutatedLayers();
return true;
}
void
@ -408,6 +306,62 @@ WebRenderLayerManager::DiscardImages()
mImageKeys.clear();
}
void
WebRenderLayerManager::AddCompositorAnimationsIdForDiscard(uint64_t aId)
{
mDiscardedCompositorAnimationsIds.push_back(aId);
}
void
WebRenderLayerManager::DiscardCompositorAnimations()
{
for (auto id : mDiscardedCompositorAnimationsIds) {
WrBridge()->AddWebRenderParentCommand(OpRemoveCompositorAnimations(id));
}
mDiscardedCompositorAnimationsIds.clear();
}
void
WebRenderLayerManager::DiscardLocalImages()
{
// Removes images but doesn't tell the parent side about them
// This is useful in empty / failed transactions where we created
// image keys but didn't tell the parent about them yet.
mImageKeys.clear();
}
void
WebRenderLayerManager::Mutated(Layer* aLayer)
{
LayerManager::Mutated(aLayer);
AddMutatedLayer(aLayer);
}
void
WebRenderLayerManager::MutatedSimple(Layer* aLayer)
{
LayerManager::Mutated(aLayer);
AddMutatedLayer(aLayer);
}
void
WebRenderLayerManager::AddMutatedLayer(Layer* aLayer)
{
mMutatedLayers.AppendElement(aLayer);
}
void
WebRenderLayerManager::ClearMutatedLayers()
{
mMutatedLayers.Clear();
}
bool
WebRenderLayerManager::IsMutatedLayer(Layer* aLayer)
{
return mMutatedLayers.Contains(aLayer);
}
void
WebRenderLayerManager::Hold(Layer* aLayer)
{
@ -516,6 +470,25 @@ WebRenderLayerManager::Composite()
WrBridge()->SendForceComposite();
}
RefPtr<PipelineIdPromise>
WebRenderLayerManager::AllocPipelineId()
{
if (XRE_IsParentProcess()) {
GPUProcessManager* pm = GPUProcessManager::Get();
if (!pm) {
return PipelineIdPromise::CreateAndReject(ipc::PromiseRejectReason::HandlerRejected, __func__);
}
return PipelineIdPromise::CreateAndResolve(wr::AsPipelineId(pm->AllocateLayerTreeId()), __func__);;
}
MOZ_ASSERT(XRE_IsContentProcess());
RefPtr<dom::ContentChild> contentChild = dom::ContentChild::GetSingleton();
if (!contentChild) {
return PipelineIdPromise::CreateAndReject(ipc::PromiseRejectReason::HandlerRejected, __func__);
}
return contentChild->SendAllocPipelineId();
}
void
WebRenderLayerManager::SetRoot(Layer* aLayer)
{

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