зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to autoland, a=merge
MozReview-Commit-ID: 6CUQEJghjzU
This commit is contained in:
Коммит
a463bb4c4c
|
@ -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)
|
||||
{
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче