author | Gurzau Raul <rgurzau@mozilla.com> |
Thu, 03 May 2018 00:04:54 +0300 | |
changeset 416731 | 2d83e1843241d869a2fc5cf06f96d3af44c70e70 |
parent 416701 | a0f7e5f1bea6466277ba96a2bd22eee6f72930c3 (current diff) |
parent 416730 | 04e165cb504fe603c1b61e1b59342bc0556a25dd (diff) |
child 416734 | 4cd21995f6d93788eeb72e5f62f59dd2861a0a2f |
child 416769 | cb245b9a8b2ce1dbe877f85566cf16613d8d9b44 |
push id | 33933 |
push user | rgurzau@mozilla.com |
push date | Wed, 02 May 2018 21:05:42 +0000 |
treeherder | mozilla-central@2d83e1843241 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | merge |
milestone | 61.0a1 |
first release with | nightly linux32
2d83e1843241
/
61.0a1
/
20180502220059
/
files
nightly linux64
2d83e1843241
/
61.0a1
/
20180502220059
/
files
nightly mac
2d83e1843241
/
61.0a1
/
20180502220059
/
files
nightly win32
2d83e1843241
/
61.0a1
/
20180502220059
/
files
nightly win64
2d83e1843241
/
61.0a1
/
20180502220059
/
files
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly linux32
61.0a1
/
20180502220059
/
pushlog to previous
nightly linux64
61.0a1
/
20180502220059
/
pushlog to previous
nightly mac
61.0a1
/
20180502220059
/
pushlog to previous
nightly win32
61.0a1
/
20180502220059
/
pushlog to previous
nightly win64
61.0a1
/
20180502220059
/
pushlog to previous
|
taskcluster/ci/release-source/source.yml | file | annotate | diff | comparison | revisions |
--- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -6935,17 +6935,17 @@ var WebAuthnPromptHelper = { this.sign(mgr, data); } else if (data.action == "cancel") { this.cancel(data); } }, register(mgr, {origin, tid}) { let mainAction = this.buildCancelAction(mgr, tid); - this.show(tid, "register", "webauthn.registerPrompt", origin, mainAction); + this.show(tid, "register", "webauthn.registerPrompt2", origin, mainAction); }, registerDirect(mgr, {origin, tid}) { let mainAction = this.buildProceedAction(mgr, tid); let secondaryActions = [this.buildCancelAction(mgr, tid)]; let learnMoreURL = Services.urlFormatter.formatURLPref("app.support.baseURL") + @@ -6953,23 +6953,23 @@ var WebAuthnPromptHelper = { let options = { learnMoreURL, checkbox: { label: gNavigatorBundle.getString("webauthn.anonymize") } }; - this.show(tid, "register-direct", "webauthn.registerDirectPrompt", + this.show(tid, "register-direct", "webauthn.registerDirectPrompt2", origin, mainAction, secondaryActions, options); }, sign(mgr, {origin, tid}) { let mainAction = this.buildCancelAction(mgr, tid); - this.show(tid, "sign", "webauthn.signPrompt", origin, mainAction); + this.show(tid, "sign", "webauthn.signPrompt2", origin, mainAction); }, show(tid, id, stringId, origin, mainAction, secondaryActions = [], options = {}) { this.reset(); try { origin = Services.io.newURI(origin).asciiHost; } catch (e) {
--- a/browser/components/preferences/in-content/main.js +++ b/browser/components/preferences/in-content/main.js @@ -2493,18 +2493,19 @@ var gMainPane = { // compute index to display download folder label and icon to avoid // displaying blank downloadFolder label and icon on load of preferences UI // Set folderIndex to 1 if currentDirPref is unspecified folderIndex = currentDirPref.value ? await this._folderToIndex(currentDirPref.value) : 1; } // Display a 'pretty' label or the path in the UI. if (folderIndex == 2) { - // Custom path selected and is configured - downloadFolder.value = currentDirPref.value ? currentDirPref.value.path : ""; + // Force the left-to-right direction when displaying a custom path. + downloadFolder.value = currentDirPref.value ? + `\u2066${currentDirPref.value.path}\u2069` : ""; iconUrlSpec = fph.getURLSpecFromFile(currentDirPref.value); } else if (folderIndex == 1) { // 'Downloads' downloadFolder.value = bundlePreferences.getString("downloadsFolderName"); iconUrlSpec = fph.getURLSpecFromFile(await this._indexToFolder(1)); } else { // 'Desktop' downloadFolder.value = bundlePreferences.getString("desktopFolderName");
--- a/browser/locales/en-US/chrome/browser/browser.properties +++ b/browser/locales/en-US/chrome/browser/browser.properties @@ -482,31 +482,31 @@ offlineApps.manageUsageAccessKey=S canvas.siteprompt=Will you allow %S to use your HTML5 canvas image data? This may be used to uniquely identify your computer. canvas.notAllow=Don’t Allow canvas.notAllow.accesskey=n canvas.allow=Allow Data Access canvas.allow.accesskey=A canvas.remember=Always remember my decision # WebAuthn prompts -# LOCALIZATION NOTE (webauthn.registerPrompt): %S is hostname -webauthn.registerPrompt=%S wants to register an account with one of your security tokens. You can connect and authorize one now, or cancel. -# LOCALIZATION NOTE (webauthn.registerDirectPrompt): +# LOCALIZATION NOTE (webauthn.registerPrompt2): %S is hostname +webauthn.registerPrompt2=%S wants to register an account with one of your security keys. You can connect and authorize one now, or cancel. +# LOCALIZATION NOTE (webauthn.registerDirectPrompt2): # %1$S is hostname. %2$S is brandShortName. # The website is asking for extended information about your # hardware authenticator that shouldn't be generally necessary. Permitting # this is safe if you only use one account at this website. If you have # multiple accounts at this website, and you use the same hardware # authenticator, then the website could link those accounts together. # And this is true even if you use a different profile / browser (or even Tor # Browser). To avoid this, you should use different hardware authenticators # for different accounts on this website. -webauthn.registerDirectPrompt=%1$S is requesting extended information about your authenticator, which may affect your privacy.\n\n%2$S can anonymize this for you, but the website might decline this authenticator. If declined, you can try again. -# LOCALIZATION NOTE (webauthn.signPrompt): %S is hostname -webauthn.signPrompt=%S wants to authenticate you using a registered security token. You can connect and authorize one now, or cancel. +webauthn.registerDirectPrompt2=%1$S is requesting extended information about your security key, which may affect your privacy.\n\n%2$S can anonymize this for you, but the website might decline this key. If declined, you can try again. +# LOCALIZATION NOTE (webauthn.signPrompt2): %S is hostname +webauthn.signPrompt2=%S wants to authenticate you using a registered security key. You can connect and authorize one now, or cancel. webauthn.cancel=Cancel webauthn.cancel.accesskey=c webauthn.proceed=Proceed webauthn.proceed.accesskey=p webauthn.anonymize=Anonymize anyway # Spoof Accept-Language prompt privacy.spoof_english=Changing your language setting to English will make you more difficult to identify and enhance your privacy. Do you want to request English language versions of web pages?
--- a/dom/base/DOMMozPromiseRequestHolder.h +++ b/dom/base/DOMMozPromiseRequestHolder.h @@ -37,16 +37,26 @@ namespace dom { * * RefPtr<DOMMozPromiseRequestHolder> holder = * new DOMMozPromiseRequestHolder(global); * * DoAsyncStuff()->Then( * global->EventTargetFor(TaskCategory::Other), __func__, * [holder, outer] (const Result& aResult) { * holder->Complete(); + * + * // Note, you can access the holder's bound global in + * // your reaction handler. Its mostly likely set if + * // the handler fires, but you still must check for + * // its existence since something could disconnect + * // the global between when the MozPromise reaction + * // runnable is queued and when it actually runs. + * nsIGlobalObject* global = holder->GetParentObject(); + * NS_ENSURE_TRUE_VOID(global); + * * outer->MaybeResolve(aResult); * }, [holder, outer] (nsresult aRv) { * holder->Complete(); * outer->MaybeReject(aRv); * })->Track(*holder); * * return outer.forget(); * } @@ -96,17 +106,16 @@ public: { return mHolder; } void Complete() { mHolder.Complete(); - DisconnectFromOwner(); } void DisconnectIfExists() { mHolder.DisconnectIfExists(); }
--- a/dom/clients/api/Client.cpp +++ b/dom/clients/api/Client.cpp @@ -6,16 +6,17 @@ #include "Client.h" #include "ClientDOMUtil.h" #include "mozilla/dom/ClientHandle.h" #include "mozilla/dom/ClientIPCTypes.h" #include "mozilla/dom/ClientManager.h" #include "mozilla/dom/ClientState.h" +#include "mozilla/dom/DOMMozPromiseRequestHolder.h" #include "mozilla/dom/Promise.h" #include "mozilla/dom/WorkerPrivate.h" #include "mozilla/dom/WorkerScope.h" #include "nsIGlobalObject.h" namespace mozilla { namespace dom { @@ -167,40 +168,33 @@ Client::Focus(ErrorResult& aRv) return outerPromise.forget(); } if (!workerPrivate->GlobalScope()->WindowInteractionAllowed()) { outerPromise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR); return outerPromise.forget(); } - // Hold the worker thread alive while we perform the async operation - // and also avoid invoking callbacks if the worker starts shutting - // down. - RefPtr<WorkerHolderToken> token = - WorkerHolderToken::Create(GetCurrentThreadWorkerPrivate(), Closing); + EnsureHandle(); - EnsureHandle(); - RefPtr<ClientStatePromise> innerPromise = mHandle->Focus(); - RefPtr<Client> self = this; + IPCClientInfo ipcClientInfo(mData->info()); + auto holder = MakeRefPtr<DOMMozPromiseRequestHolder<ClientStatePromise>>(mGlobal); - innerPromise->Then(mGlobal->EventTargetFor(TaskCategory::Other), __func__, - [self, token, outerPromise] (const ClientState& aResult) { - if (token->IsShuttingDown()) { - return; - } - RefPtr<Client> newClient = - new Client(self->mGlobal, ClientInfoAndState(self->mData->info(), aResult.ToIPC())); + mHandle->Focus()->Then(mGlobal->EventTargetFor(TaskCategory::Other), __func__, + [ipcClientInfo, holder, outerPromise] (const ClientState& aResult) { + holder->Complete(); + NS_ENSURE_TRUE_VOID(holder->GetParentObject()); + RefPtr<Client> newClient = new Client(holder->GetParentObject(), + ClientInfoAndState(ipcClientInfo, + aResult.ToIPC())); outerPromise->MaybeResolve(newClient); - }, [self, token, outerPromise] (nsresult aResult) { - if (token->IsShuttingDown()) { - return; - } + }, [holder, outerPromise] (nsresult aResult) { + holder->Complete(); outerPromise->MaybeReject(aResult); - }); + })->Track(*holder); return outerPromise.forget(); } already_AddRefed<Promise> Client::Navigate(const nsAString& aURL, ErrorResult& aRv) { MOZ_ASSERT(!NS_IsMainThread()); @@ -213,18 +207,17 @@ Client::Navigate(const nsAString& aURL, if (aRv.Failed()) { return outerPromise.forget(); } ClientNavigateArgs args(mData->info(), NS_ConvertUTF16toUTF8(aURL), workerPrivate->GetLocationInfo().mHref); RefPtr<Client> self = this; - StartClientManagerOp(&ClientManager::Navigate, args, - mGlobal->EventTargetFor(TaskCategory::Other), + StartClientManagerOp(&ClientManager::Navigate, args, mGlobal, [self, outerPromise] (const ClientOpResult& aResult) { if (aResult.type() != ClientOpResult::TClientInfoAndState) { outerPromise->MaybeResolve(JS::NullHandleValue); return; } RefPtr<Client> newClient = new Client(self->mGlobal, aResult.get_ClientInfoAndState()); outerPromise->MaybeResolve(newClient);
--- a/dom/clients/api/ClientDOMUtil.h +++ b/dom/clients/api/ClientDOMUtil.h @@ -3,49 +3,47 @@ /* 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 _mozilla_dom_ClientDOMUtil_h #define _mozilla_dom_ClientDOMUtil_h #include "mozilla/dom/ClientIPCTypes.h" #include "mozilla/dom/ClientOpPromise.h" +#include "mozilla/dom/DOMMozPromiseRequestHolder.h" #include "mozilla/dom/WorkerHolderToken.h" #include "mozilla/dom/WorkerPrivate.h" class nsIGlobalObject; namespace mozilla { namespace dom { // Utility method to properly execute a ClientManager operation. It // will properly hold a worker thread alive and avoid executing callbacks // if the thread is shutting down. template<typename Func, typename Arg, typename Resolve, typename Reject> void -StartClientManagerOp(Func aFunc, const Arg& aArg, nsISerialEventTarget* aTarget, +StartClientManagerOp(Func aFunc, const Arg& aArg, nsIGlobalObject* aGlobal, Resolve aResolve, Reject aReject) { - RefPtr<WorkerHolderToken> token; - if (!NS_IsMainThread()) { - token = WorkerHolderToken::Create(GetCurrentThreadWorkerPrivate(), - WorkerStatus::Closing); - } + MOZ_DIAGNOSTIC_ASSERT(aGlobal); + + nsCOMPtr<nsISerialEventTarget> target = + aGlobal->EventTargetFor(TaskCategory::Other); + + auto holder = MakeRefPtr<DOMMozPromiseRequestHolder<ClientOpPromise>>(aGlobal); - RefPtr<ClientOpPromise> promise = aFunc(aArg, aTarget); - promise->Then(aTarget, __func__, - [aResolve, token](const ClientOpResult& aResult) { - if (token && token->IsShuttingDown()) { - return; - } + aFunc(aArg, target)->Then( + target, __func__, + [aResolve, holder](const ClientOpResult& aResult) { + holder->Complete(); aResolve(aResult); - }, [aReject, token](nsresult aResult) { - if (token && token->IsShuttingDown()) { - return; - } + }, [aReject, holder](nsresult aResult) { + holder->Complete(); aReject(aResult); - }); + })->Track(*holder); } } // namespace dom } // namespace mozilla #endif // _mozilla_dom_ClientDOMUtil_h
--- a/dom/clients/api/Clients.cpp +++ b/dom/clients/api/Clients.cpp @@ -79,37 +79,41 @@ Clients::Get(const nsAString& aClientID, const PrincipalInfo& principalInfo = workerPrivate->GetPrincipalInfo(); nsCOMPtr<nsISerialEventTarget> target = mGlobal->EventTargetFor(TaskCategory::Other); RefPtr<ClientOpPromise> innerPromise = ClientManager::GetInfoAndState(ClientGetInfoAndStateArgs(id, principalInfo), target); - nsCOMPtr<nsIGlobalObject> global = mGlobal; nsCString scope = workerPrivate->ServiceWorkerScope(); + auto holder = MakeRefPtr<DOMMozPromiseRequestHolder<ClientOpPromise>>(mGlobal); innerPromise->Then(target, __func__, - [outerPromise, global, scope] (const ClientOpResult& aResult) { - RefPtr<Client> client = new Client(global, aResult.get_ClientInfoAndState()); + [outerPromise, holder, scope] (const ClientOpResult& aResult) { + holder->Complete(); + NS_ENSURE_TRUE_VOID(holder->GetParentObject()); + RefPtr<Client> client = new Client(holder->GetParentObject(), + aResult.get_ClientInfoAndState()); if (client->GetStorageAccess() == nsContentUtils::StorageAccess::eAllow) { outerPromise->MaybeResolve(Move(client)); return; } nsCOMPtr<nsIRunnable> r = - NS_NewRunnableFunction("Clients::MatchAll() storage denied", + NS_NewRunnableFunction("Clients::Get() storage denied", [scope] { ServiceWorkerManager::LocalizeAndReportToAllClients( scope, "ServiceWorkerGetClientStorageError", nsTArray<nsString>()); }); SystemGroup::Dispatch(TaskCategory::Other, r.forget()); outerPromise->MaybeResolveWithUndefined(); - }, [outerPromise] (nsresult aResult) { + }, [outerPromise, holder] (nsresult aResult) { + holder->Complete(); outerPromise->MaybeResolveWithUndefined(); - }); + })->Track(*holder); return outerPromise.forget(); } namespace { class MatchAllComparator final { @@ -161,18 +165,17 @@ Clients::MatchAll(const ClientQueryOptio } nsCOMPtr<nsIGlobalObject> global = mGlobal; nsCString scope = workerPrivate->ServiceWorkerScope(); ClientMatchAllArgs args(workerPrivate->GetServiceWorkerDescriptor().ToIPC(), aOptions.mType, aOptions.mIncludeUncontrolled); - StartClientManagerOp(&ClientManager::MatchAll, args, - mGlobal->EventTargetFor(TaskCategory::Other), + StartClientManagerOp(&ClientManager::MatchAll, args, mGlobal, [outerPromise, global, scope] (const ClientOpResult& aResult) { nsTArray<RefPtr<Client>> clientList; bool storageDenied = false; for (const ClientInfoAndState& value : aResult.get_ClientList().values()) { RefPtr<Client> client = new Client(global, value); if (client->GetStorageAccess() != nsContentUtils::StorageAccess::eAllow) { storageDenied = true; continue; @@ -224,18 +227,17 @@ Clients::OpenWindow(const nsAString& aUR const PrincipalInfo& principalInfo = workerPrivate->GetPrincipalInfo(); nsCString baseURL = workerPrivate->GetLocationInfo().mHref; ClientOpenWindowArgs args(principalInfo, NS_ConvertUTF16toUTF8(aURL), baseURL); nsCOMPtr<nsIGlobalObject> global = mGlobal; - StartClientManagerOp(&ClientManager::OpenWindow, args, - mGlobal->EventTargetFor(TaskCategory::Other), + StartClientManagerOp(&ClientManager::OpenWindow, args, mGlobal, [outerPromise, global] (const ClientOpResult& aResult) { if (aResult.type() != ClientOpResult::TClientInfoAndState) { outerPromise->MaybeResolve(JS::NullHandleValue); return; } RefPtr<Client> client = new Client(global, aResult.get_ClientInfoAndState()); outerPromise->MaybeResolve(client); @@ -266,18 +268,18 @@ Clients::Claim(ErrorResult& aRv) workerPrivate->GetServiceWorkerDescriptor(); if (serviceWorker.State() != ServiceWorkerState::Activating && serviceWorker.State() != ServiceWorkerState::Activated) { aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); return outerPromise.forget(); } - StartClientManagerOp(&ClientManager::Claim, ClientClaimArgs(serviceWorker.ToIPC()), - mGlobal->EventTargetFor(TaskCategory::Other), + StartClientManagerOp( + &ClientManager::Claim, ClientClaimArgs(serviceWorker.ToIPC()), mGlobal, [outerPromise] (const ClientOpResult& aResult) { outerPromise->MaybeResolveWithUndefined(); }, [outerPromise] (nsresult aResult) { outerPromise->MaybeReject(aResult); }); return outerPromise.forget(); }
--- a/dom/clients/manager/ClientHandle.cpp +++ b/dom/clients/manager/ClientHandle.cpp @@ -32,42 +32,37 @@ ClientHandle::Shutdown() return; } ShutdownThing(); mManager = nullptr; } -already_AddRefed<ClientOpPromise> -ClientHandle::StartOp(const ClientOpConstructorArgs& aArgs) +void +ClientHandle::StartOp(const ClientOpConstructorArgs& aArgs, + const ClientOpCallback&& aResolveCallback, + const ClientOpCallback&& aRejectCallback) { - RefPtr<ClientOpPromise::Private> promise = - new ClientOpPromise::Private(__func__); - // Hold a ref to the client until the remote operation completes. Otherwise // the ClientHandle might get de-refed and teardown the actor before we // get an answer. RefPtr<ClientHandle> kungFuGrip = this; - promise->Then(mSerialEventTarget, __func__, - [kungFuGrip] (const ClientOpResult &) { }, - [kungFuGrip] (nsresult) { }); - MaybeExecute([aArgs, promise] (ClientHandleChild* aActor) { - ClientHandleOpChild* actor = new ClientHandleOpChild(aArgs, promise); + MaybeExecute([aArgs, kungFuGrip, aRejectCallback, + resolve = Move(aResolveCallback)] (ClientHandleChild* aActor) { + ClientHandleOpChild* actor = + new ClientHandleOpChild(aArgs, Move(resolve), Move(aRejectCallback)); if (!aActor->SendPClientHandleOpConstructor(actor, aArgs)) { - // Constructor failure will reject promise via ActorDestroy() + // Constructor failure will call reject callback via ActorDestroy() return; } - }, [promise] { - promise->Reject(NS_ERROR_DOM_INVALID_STATE_ERR, __func__); + }, [aRejectCallback, kungFuGrip] { + aRejectCallback(NS_ERROR_DOM_INVALID_STATE_ERR); }); - - RefPtr<ClientOpPromise> ref = promise.get(); - return ref.forget(); } void ClientHandle::OnShutdownThing() { NS_ASSERT_OWNINGTHREAD(ClientHandle); if (!mDetachPromise) { return; @@ -119,39 +114,34 @@ ClientHandle::Info() const } RefPtr<GenericPromise> ClientHandle::Control(const ServiceWorkerDescriptor& aServiceWorker) { RefPtr<GenericPromise::Private> outerPromise = new GenericPromise::Private(__func__); - RefPtr<ClientOpPromise> innerPromise = - StartOp(ClientControlledArgs(aServiceWorker.ToIPC())); - - innerPromise->Then(mSerialEventTarget, __func__, + StartOp(ClientControlledArgs(aServiceWorker.ToIPC()), [outerPromise](const ClientOpResult& aResult) { outerPromise->Resolve(true, __func__); }, [outerPromise](const ClientOpResult& aResult) { outerPromise->Reject(aResult.get_nsresult(), __func__); }); return outerPromise.forget(); } RefPtr<ClientStatePromise> ClientHandle::Focus() { RefPtr<ClientStatePromise::Private> outerPromise = new ClientStatePromise::Private(__func__); - RefPtr<ClientOpPromise> innerPromise = StartOp(ClientFocusArgs()); - - innerPromise->Then(mSerialEventTarget, __func__, + StartOp(ClientFocusArgs(), [outerPromise](const ClientOpResult& aResult) { outerPromise->Resolve(ClientState::FromIPC(aResult.get_IPCClientState()), __func__); }, [outerPromise](const ClientOpResult& aResult) { outerPromise->Reject(aResult.get_nsresult(), __func__); }); RefPtr<ClientStatePromise> ref = outerPromise.get(); return ref.forget(); @@ -175,18 +165,17 @@ ClientHandle::PostMessage(StructuredClon args.clonedData())) { ref = GenericPromise::CreateAndReject(NS_ERROR_DOM_INVALID_STATE_ERR, __func__); return ref.forget(); } RefPtr<GenericPromise::Private> outerPromise = new GenericPromise::Private(__func__); - RefPtr<ClientOpPromise> innerPromise = StartOp(args); - innerPromise->Then(mSerialEventTarget, __func__, + StartOp(args, [outerPromise](const ClientOpResult& aResult) { outerPromise->Resolve(true, __func__); }, [outerPromise](const ClientOpResult& aResult) { outerPromise->Reject(aResult.get_nsresult(), __func__); }); ref = outerPromise.get(); return ref.forget();
--- a/dom/clients/manager/ClientHandle.h +++ b/dom/clients/manager/ClientHandle.h @@ -45,18 +45,20 @@ class ClientHandle final : public Client RefPtr<GenericPromise::Private> mDetachPromise; ClientInfo mClientInfo; ~ClientHandle(); void Shutdown(); - already_AddRefed<ClientOpPromise> - StartOp(const ClientOpConstructorArgs& aArgs); + void + StartOp(const ClientOpConstructorArgs& aArgs, + const ClientOpCallback&& aResolveCallback, + const ClientOpCallback&& aRejectCallback); // ClientThing interface void OnShutdownThing() override; // Private methods called by ClientHandleChild void ExecutionReady(const ClientInfo& aClientInfo);
--- a/dom/clients/manager/ClientHandleOpChild.cpp +++ b/dom/clients/manager/ClientHandleOpChild.cpp @@ -7,42 +7,35 @@ #include "ClientHandleOpChild.h" namespace mozilla { namespace dom { void ClientHandleOpChild::ActorDestroy(ActorDestroyReason aReason) { - if (mPromise) { - mPromise->Reject(NS_ERROR_ABORT, __func__); - mPromise = nullptr; - } + mRejectCallback(NS_ERROR_DOM_ABORT_ERR); } mozilla::ipc::IPCResult ClientHandleOpChild::Recv__delete__(const ClientOpResult& aResult) { if (aResult.type() == ClientOpResult::Tnsresult && NS_FAILED(aResult.get_nsresult())) { - mPromise->Reject(aResult.get_nsresult(), __func__); - mPromise = nullptr; + mRejectCallback(aResult.get_nsresult()); return IPC_OK(); } - mPromise->Resolve(aResult, __func__); - mPromise = nullptr; + mResolveCallback(aResult); return IPC_OK(); } ClientHandleOpChild::ClientHandleOpChild(const ClientOpConstructorArgs& aArgs, - ClientOpPromise::Private* aPromise) - : mPromise(aPromise) + const ClientOpCallback&& aResolveCallback, + const ClientOpCallback&& aRejectCallback) + : mResolveCallback(Move(aResolveCallback)) + , mRejectCallback(Move(aRejectCallback)) { - MOZ_DIAGNOSTIC_ASSERT(mPromise); -} - -ClientHandleOpChild::~ClientHandleOpChild() -{ - MOZ_DIAGNOSTIC_ASSERT(!mPromise); + MOZ_DIAGNOSTIC_ASSERT(mResolveCallback); + MOZ_DIAGNOSTIC_ASSERT(mRejectCallback); } } // namespace dom } // namespace mozilla
--- a/dom/clients/manager/ClientHandleOpChild.h +++ b/dom/clients/manager/ClientHandleOpChild.h @@ -3,35 +3,36 @@ /* 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 _mozilla_dom_ClientHandleOpChild_h #define _mozilla_dom_ClientHandleOpChild_h #include "mozilla/dom/ClientOpPromise.h" #include "mozilla/dom/PClientHandleOpChild.h" -#include "mozilla/MozPromise.h" namespace mozilla { namespace dom { class ClientHandleOpChild final : public PClientHandleOpChild { - RefPtr<ClientOpPromise::Private> mPromise; + const ClientOpCallback mResolveCallback; + const ClientOpCallback mRejectCallback; // PClientHandleOpChild interface void ActorDestroy(ActorDestroyReason aReason) override; mozilla::ipc::IPCResult Recv__delete__(const ClientOpResult& aResult) override; public: ClientHandleOpChild(const ClientOpConstructorArgs& aArgs, - ClientOpPromise::Private* aPromise); + const ClientOpCallback&& aResolveCallback, + const ClientOpCallback&& aRejectCallback); - ~ClientHandleOpChild(); + ~ClientHandleOpChild() = default; }; } // namespace dom } // namespace mozilla #endif // _mozilla_dom_ClientHandleOpChild_h
--- a/dom/clients/manager/ClientManager.cpp +++ b/dom/clients/manager/ClientManager.cpp @@ -40,18 +40,25 @@ ClientManager::ClientManager() return; } RefPtr<WorkerHolderToken> workerHolderToken; if (!NS_IsMainThread()) { WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); MOZ_DIAGNOSTIC_ASSERT(workerPrivate); + // Note, it would be nice to replace this with a WorkerRef, but + // currently there is no WorkerRef option that matches what we + // need here. We need something like a StrongWorkerRef that will + // let us keep the worker alive until our actor is destroyed, but + // we also need to use AllowIdleShutdownStart like WeakWorkerRef. + // We need AllowIdleShutdownStart since every worker thread will + // have a ClientManager to support creating its ClientSource. workerHolderToken = - WorkerHolderToken::Create(workerPrivate, Closing, + WorkerHolderToken::Create(workerPrivate, Terminating, WorkerHolderToken::AllowIdleShutdownStart); if (NS_WARN_IF(!workerHolderToken)) { Shutdown(); return; } } ClientManagerChild* actor = new ClientManagerChild(workerHolderToken);
--- a/dom/clients/manager/ClientOpPromise.h +++ b/dom/clients/manager/ClientOpPromise.h @@ -13,12 +13,14 @@ namespace dom { class ClientOpResult; class ClientState; typedef MozPromise<ClientOpResult, nsresult, false> ClientOpPromise; typedef MozPromise<ClientState, nsresult, false> ClientStatePromise; +typedef std::function<void(const ClientOpResult&)> ClientOpCallback; + } // namespace dom } // namespace mozilla #endif // _mozilla_dom_ClientOpPromise_h
--- a/dom/clients/manager/ClientSource.cpp +++ b/dom/clients/manager/ClientSource.cpp @@ -8,16 +8,17 @@ #include "ClientManager.h" #include "ClientManagerChild.h" #include "ClientPrincipalUtils.h" #include "ClientSourceChild.h" #include "ClientState.h" #include "ClientValidation.h" #include "mozilla/dom/ClientIPCTypes.h" +#include "mozilla/dom/DOMMozPromiseRequestHolder.h" #include "mozilla/dom/ipc/StructuredCloneData.h" #include "mozilla/dom/MessageEvent.h" #include "mozilla/dom/MessageEventBinding.h" #include "mozilla/dom/Navigator.h" #include "mozilla/dom/WorkerPrivate.h" #include "mozilla/dom/WorkerScope.h" #include "mozilla/dom/ServiceWorker.h" #include "mozilla/dom/ServiceWorkerContainer.h" @@ -631,23 +632,28 @@ ClientSource::Claim(const ClientClaimArg SetController(swd); ref = ClientOpPromise::CreateAndResolve(NS_OK, __func__); return ref.forget(); } RefPtr<ClientOpPromise::Private> outerPromise = new ClientOpPromise::Private(__func__); + auto holder = + MakeRefPtr<DOMMozPromiseRequestHolder<GenericPromise>>(innerWindow->AsGlobal()); + RefPtr<GenericPromise> p = swm->MaybeClaimClient(doc, swd); p->Then(mEventTarget, __func__, - [outerPromise] (bool aResult) { + [outerPromise, holder] (bool aResult) { + holder->Complete(); outerPromise->Resolve(NS_OK, __func__); - }, [outerPromise] (nsresult aResult) { + }, [outerPromise, holder] (nsresult aResult) { + holder->Complete(); outerPromise->Reject(aResult, __func__); - }); + })->Track(*holder); ref = outerPromise; return ref.forget(); } RefPtr<ClientOpPromise> ClientSource::GetInfoAndState(const ClientGetInfoAndStateArgs& aArgs) {
--- a/dom/fetch/Fetch.cpp +++ b/dom/fetch/Fetch.cpp @@ -530,18 +530,24 @@ FetchRequest(nsIGlobalObject* aGlobal, c RefPtr<WorkerFetchResolver> resolver = WorkerFetchResolver::Create(worker, p, signal, observer); if (!resolver) { NS_WARNING("Could not keep the worker alive."); aRv.Throw(NS_ERROR_DOM_ABORT_ERR); return nullptr; } + Maybe<ClientInfo> clientInfo(worker->GetClientInfo()); + if (clientInfo.isNothing()) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return nullptr; + } + RefPtr<MainThreadFetchRunnable> run = - new MainThreadFetchRunnable(resolver, worker->GetClientInfo(), + new MainThreadFetchRunnable(resolver, clientInfo.ref(), worker->GetController(), r); worker->DispatchToMainThread(run.forget()); } return p.forget(); } void
--- a/dom/smil/moz.build +++ b/dom/smil/moz.build @@ -11,16 +11,17 @@ MOCHITEST_MANIFESTS += ['test/mochitest. EXPORTS += [ 'nsISMILAttr.h', 'nsISMILType.h', 'nsSMILAnimationController.h', 'nsSMILAnimationFunction.h', 'nsSMILCompositorTable.h', 'nsSMILCSSProperty.h', + 'nsSMILCSSValueType.h', 'nsSMILInstanceTime.h', 'nsSMILInterval.h', 'nsSMILKeySpline.h', 'nsSMILMilestone.h', 'nsSMILNullType.h', 'nsSMILRepeatCount.h', 'nsSMILSetAnimationFunction.h', 'nsSMILTargetIdentifier.h',
--- a/dom/smil/nsSMILCSSProperty.cpp +++ b/dom/smil/nsSMILCSSProperty.cpp @@ -102,32 +102,17 @@ nsSMILCSSProperty::ValueFromString(const } return NS_OK; } nsresult nsSMILCSSProperty::SetAnimValue(const nsSMILValue& aValue) { NS_ENSURE_TRUE(IsPropertyAnimatable(mPropID), NS_ERROR_FAILURE); - - // Convert nsSMILValue to string - nsAutoString valStr; - nsSMILCSSValueType::ValueToString(aValue, valStr); - - // Use string value to style the target element - nsDOMCSSAttributeDeclaration* overrideDecl = mElement->GetSMILOverrideStyle(); - if (overrideDecl) { - nsAutoString oldValStr; - overrideDecl->GetPropertyValue(mPropID, oldValStr); - if (valStr.Equals(oldValStr)) { - return NS_OK; - } - overrideDecl->SetPropertyValue(mPropID, valStr, nullptr); - } - return NS_OK; + return mElement->GetSMILOverrideStyle()->SetSMILValue(mPropID, aValue); } void nsSMILCSSProperty::ClearAnimValue() { // Put empty string in override style for our property nsDOMCSSAttributeDeclaration* overrideDecl = mElement->GetSMILOverrideStyle(); if (overrideDecl) {
--- a/dom/workers/ScriptLoader.cpp +++ b/dom/workers/ScriptLoader.cpp @@ -1905,17 +1905,19 @@ class ChannelGetterRunnable final : publ public: ChannelGetterRunnable(WorkerPrivate* aParentWorker, const nsAString& aScriptURL, WorkerLoadInfo& aLoadInfo) : WorkerMainThreadRunnable(aParentWorker, NS_LITERAL_CSTRING("ScriptLoader :: ChannelGetter")) , mScriptURL(aScriptURL) - , mClientInfo(aParentWorker->GetClientInfo()) + // ClientInfo should always be present since this should not be called + // if parent's status is greater than Running. + , mClientInfo(aParentWorker->GetClientInfo().ref()) , mLoadInfo(aLoadInfo) , mResult(NS_ERROR_FAILURE) { MOZ_ASSERT(aParentWorker); aParentWorker->AssertIsOnWorkerThread(); } virtual bool @@ -2241,17 +2243,17 @@ LoadAllScripts(WorkerPrivate* aWorkerPri if (!syncLoopTarget) { aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); return; } Maybe<ClientInfo> clientInfo; Maybe<ServiceWorkerDescriptor> controller; if (!aIsMainScript) { - clientInfo.emplace(aWorkerPrivate->GetClientInfo()); + clientInfo = aWorkerPrivate->GetClientInfo(); controller = aWorkerPrivate->GetController(); } RefPtr<ScriptLoaderRunnable> loader = new ScriptLoaderRunnable(aWorkerPrivate, syncLoopTarget, aLoadInfos, clientInfo, controller, aIsMainScript, aWorkerScriptType, aRv); @@ -2385,17 +2387,17 @@ LoadMainScript(WorkerPrivate* aWorkerPri nsTArray<ScriptLoadInfo> loadInfos; ScriptLoadInfo* info = loadInfos.AppendElement(); info->mURL = aScriptURL; info->mLoadFlags = aWorkerPrivate->GetLoadFlags(); // We are loading the main script, so the worker's Client must be // reserved. - info->mReservedClientInfo.emplace(aWorkerPrivate->GetClientInfo()); + info->mReservedClientInfo = aWorkerPrivate->GetClientInfo(); LoadAllScripts(aWorkerPrivate, loadInfos, true, aWorkerScriptType, aRv); } void Load(WorkerPrivate* aWorkerPrivate, const nsTArray<nsString>& aScriptURLs, WorkerScriptType aWorkerScriptType, ErrorResult& aRv)
--- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -3273,22 +3273,24 @@ WorkerPrivate::DoRunLoop(JSContext* aCx) MOZ_ASSERT(currentStatus == Killing); #else currentStatus = Killing; #endif } // If we're supposed to die then we should exit the loop. if (currentStatus == Killing) { + // The ClientSource should be cleared in NotifyInternal() when we reach + // or pass Terminating. + MOZ_DIAGNOSTIC_ASSERT(!mClientSource); + // Flush uncaught rejections immediately, without // waiting for a next tick. PromiseDebugging::FlushUncaughtRejections(); - mClientSource = nullptr; - ShutdownGCTimers(); DisableMemoryReporter(); { MutexAutoLock lock(mMutex); mStatus = Dead; @@ -3495,22 +3497,27 @@ WorkerPrivate::EnsurePerformanceStorage( { AssertIsOnWorkerThread(); if (!mPerformanceStorage) { mPerformanceStorage = PerformanceStorageWorker::Create(this); } } -const ClientInfo& +Maybe<ClientInfo> WorkerPrivate::GetClientInfo() const { AssertIsOnWorkerThread(); - MOZ_DIAGNOSTIC_ASSERT(mClientSource); - return mClientSource->Info(); + Maybe<ClientInfo> clientInfo; + if (!mClientSource) { + MOZ_DIAGNOSTIC_ASSERT(mStatus >= Terminating); + return Move(clientInfo); + } + clientInfo.emplace(mClientSource->Info()); + return Move(clientInfo); } const ClientState WorkerPrivate::GetClientState() const { AssertIsOnWorkerThread(); MOZ_DIAGNOSTIC_ASSERT(mClientSource); ClientState state; @@ -3535,16 +3542,22 @@ WorkerPrivate::Control(const ServiceWork MOZ_DIAGNOSTIC_ASSERT(Type() != WorkerTypeService); mClientSource->SetController(aServiceWorker); } void WorkerPrivate::ExecutionReady() { AssertIsOnWorkerThread(); + { + MutexAutoLock lock(mMutex); + if (mStatus >= Terminating) { + return; + } + } MOZ_DIAGNOSTIC_ASSERT(mClientSource); mClientSource->WorkerExecutionReady(this); } void WorkerPrivate::InitializeGCTimers() { AssertIsOnWorkerThread(); @@ -4509,18 +4522,19 @@ WorkerPrivate::NotifyInternal(WorkerStat { MutexAutoLock lock(mMutex); if (mStatus >= aStatus) { return true; } if (aStatus >= Terminating) { + MutexAutoUnlock unlock(mMutex); + mClientSource.reset(); if (mScope) { - MutexAutoUnlock unlock(mMutex); mScope->NoteTerminating(); } } // Make sure the hybrid event target stops dispatching runnables // once we reaching the killing state. if (aStatus == Killing) { // To avoid deadlock we always acquire the event target mutex before the
--- a/dom/workers/WorkerPrivate.h +++ b/dom/workers/WorkerPrivate.h @@ -548,17 +548,17 @@ public: EnsureClientSource(); void EnsurePerformanceStorage(); void EnsurePerformanceCounter(); - const ClientInfo& + Maybe<ClientInfo> GetClientInfo() const; const ClientState GetClientState() const; const Maybe<ServiceWorkerDescriptor> GetController() const;
--- a/dom/workers/WorkerScope.cpp +++ b/dom/workers/WorkerScope.cpp @@ -541,19 +541,17 @@ AbstractThread* WorkerGlobalScope::AbstractMainThreadFor(TaskCategory aCategory) { MOZ_CRASH("AbstractMainThreadFor not supported for workers."); } Maybe<ClientInfo> WorkerGlobalScope::GetClientInfo() const { - Maybe<ClientInfo> info; - info.emplace(mWorkerPrivate->GetClientInfo()); - return Move(info); + return mWorkerPrivate->GetClientInfo(); } Maybe<ClientState> WorkerGlobalScope::GetClientState() const { Maybe<ClientState> state; state.emplace(mWorkerPrivate->GetClientState()); return Move(state);
--- a/dom/xhr/XMLHttpRequestWorker.cpp +++ b/dom/xhr/XMLHttpRequestWorker.cpp @@ -1870,17 +1870,22 @@ XMLHttpRequestWorker::Open(const nsACStr if (mProxy) { MaybeDispatchPrematureAbortEvents(aRv); if (aRv.Failed()) { return; } } else { - mProxy = new Proxy(this, mWorkerPrivate->GetClientInfo(), + Maybe<ClientInfo> clientInfo(mWorkerPrivate->GetClientInfo()); + if (clientInfo.isNothing()) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return; + } + mProxy = new Proxy(this, clientInfo.ref(), mWorkerPrivate->GetController(), mMozAnon, mMozSystem); } mProxy->mOuterEventStreamId++; RefPtr<OpenRunnable> runnable = new OpenRunnable(mWorkerPrivate, mProxy, aMethod, aUrl, aUser, aPassword, mBackgroundRequest, mWithCredentials,
--- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -1785,17 +1785,17 @@ gfxPlatform::GetLayerDiagnosticTypes() } if (gfxPrefs::FlashLayerBorders()) { type |= mozilla::layers::DiagnosticTypes::FLASH_BORDERS; } return type; } BackendPrefsData -gfxPlatform::GetBackendPrefs() +gfxPlatform::GetBackendPrefs() const { BackendPrefsData data; data.mCanvasBitmask = BackendTypeBit(BackendType::CAIRO); data.mContentBitmask = BackendTypeBit(BackendType::CAIRO); #ifdef USE_SKIA data.mCanvasBitmask |= BackendTypeBit(BackendType::SKIA); data.mContentBitmask |= BackendTypeBit(BackendType::SKIA); @@ -2711,24 +2711,50 @@ gfxPlatform::UsesOffMainThreadCompositin } return result; } bool gfxPlatform::UsesTiling() const { - bool isSkiaPOMTP = XRE_IsContentProcess() && - GetDefaultContentBackend() == BackendType::SKIA && - gfxVars::UseOMTP() && - (gfxPrefs::LayersOMTPPaintWorkers() == -1 || + bool usesSkia = GetDefaultContentBackend() == BackendType::SKIA; + + // We can't just test whether the PaintThread is initialized here because + // this function is used when initializing the PaintThread. So instead we + // check the conditions that enable OMTP with parallel painting. + bool usesPOMTP = XRE_IsContentProcess() && + gfxVars::UseOMTP() && + (gfxPrefs::LayersOMTPPaintWorkers() == -1 || gfxPrefs::LayersOMTPPaintWorkers() > 1); return gfxPrefs::LayersTilesEnabled() || - (gfxPrefs::LayersTilesEnabledIfSkiaPOMTP() && isSkiaPOMTP); + (gfxPrefs::LayersTilesEnabledIfSkiaPOMTP() && + usesSkia && + usesPOMTP); +} + +bool +gfxPlatform::ContentUsesTiling() const +{ + BackendPrefsData data = GetBackendPrefs(); + BackendType contentBackend = GetContentBackendPref(data.mContentBitmask); + if (contentBackend == BackendType::NONE) { + contentBackend = data.mContentDefault; + } + + bool contentUsesSkia = contentBackend == BackendType::SKIA; + bool contentUsesPOMTP = gfxVars::UseOMTP() && + (gfxPrefs::LayersOMTPPaintWorkers() == -1 || + gfxPrefs::LayersOMTPPaintWorkers() > 1); + + return gfxPrefs::LayersTilesEnabled() || + (gfxPrefs::LayersTilesEnabledIfSkiaPOMTP() && + contentUsesSkia && + contentUsesPOMTP); } /*** * The preference "layout.frame_rate" has 3 meanings depending on the value: * * -1 = Auto (default), use hardware vsync or software vsync @ 60 hz if hw vsync fails. * 0 = ASAP mode - used during talos testing. * X = Software vsync at a rate of X times per second.
--- a/gfx/thebes/gfxPlatform.h +++ b/gfx/thebes/gfxPlatform.h @@ -587,19 +587,28 @@ public: virtual mozilla::gfx::SurfaceFormat Optimal2DFormatForContent(gfxContentType aContent); virtual gfxImageFormat OptimalFormatForContent(gfxContentType aContent); virtual gfxImageFormat GetOffscreenFormat() { return mozilla::gfx::SurfaceFormat::X8R8G8B8_UINT32; } + /** + * Returns whether the current process should use tiling for layers. + */ virtual bool UsesTiling() const; /** + * Returns whether the content process will use tiling for layers. This is + * only used by about:support. + */ + virtual bool ContentUsesTiling() const; + + /** * Returns a logger if one is available and logging is enabled */ static mozilla::LogModule* GetLog(eGfxLog aWhichLog); int GetScreenDepth() const { return mScreenDepth; } mozilla::gfx::IntSize GetScreenSize() const { return mScreenSize; } /** @@ -752,17 +761,17 @@ protected: // Returns whether or not layers should be accelerated by default on this platform. virtual bool AccelerateLayersByDefault(); // Returns a prioritized list of available compositor backends for acceleration. virtual void GetAcceleratedCompositorBackends(nsTArray<mozilla::layers::LayersBackend>& aBackends); // Returns preferences of canvas and content backends. - virtual BackendPrefsData GetBackendPrefs(); + virtual BackendPrefsData GetBackendPrefs() const; /** * Initialise the preferred and fallback canvas backends * aBackendBitmask specifies the backends which are acceptable to the caller. * The backend used is determined by aBackendBitmask and the order specified * by the gfx.canvas.azure.backends pref. */ void InitBackendPrefs(BackendPrefsData&& aPrefsData);
--- a/gfx/thebes/gfxPlatformMac.cpp +++ b/gfx/thebes/gfxPlatformMac.cpp @@ -97,17 +97,17 @@ gfxPlatformMac::gfxPlatformMac() } gfxPlatformMac::~gfxPlatformMac() { gfxCoreTextShaper::Shutdown(); } BackendPrefsData -gfxPlatformMac::GetBackendPrefs() +gfxPlatformMac::GetBackendPrefs() const { BackendPrefsData data; data.mCanvasBitmask = BackendTypeBit(BackendType::SKIA); data.mContentBitmask = BackendTypeBit(BackendType::SKIA); data.mCanvasDefault = BackendType::SKIA; data.mContentDefault = BackendType::SKIA; @@ -117,16 +117,22 @@ gfxPlatformMac::GetBackendPrefs() bool gfxPlatformMac::UsesTiling() const { // The non-tiling ContentClient requires CrossProcessSemaphore which // isn't implemented for OSX. return true; } +bool +gfxPlatformMac::ContentUsesTiling() const +{ + return UsesTiling(); +} + gfxPlatformFontList* gfxPlatformMac::CreatePlatformFontList() { gfxPlatformFontList* list = new gfxMacPlatformFontList(); if (NS_SUCCEEDED(list->InitFontList())) { return list; } gfxPlatformFontList::Shutdown();
--- a/gfx/thebes/gfxPlatformMac.h +++ b/gfx/thebes/gfxPlatformMac.h @@ -22,16 +22,17 @@ public: gfxPlatformMac(); virtual ~gfxPlatformMac(); static gfxPlatformMac *GetPlatform() { return (gfxPlatformMac*) gfxPlatform::GetPlatform(); } bool UsesTiling() const override; + bool ContentUsesTiling() const override; virtual already_AddRefed<gfxASurface> CreateOffscreenSurface(const IntSize& aSize, gfxImageFormat aFormat) override; gfxFontGroup* CreateFontGroup(const mozilla::FontFamilyList& aFontFamilyList, const gfxFontStyle *aStyle, @@ -78,17 +79,17 @@ public: virtual already_AddRefed<mozilla::gfx::VsyncSource> CreateHardwareVsyncSource() override; // lower threshold on font anti-aliasing uint32_t GetAntiAliasingThreshold() { return mFontAntiAliasingThreshold; } protected: bool AccelerateLayersByDefault() override; - BackendPrefsData GetBackendPrefs() override; + BackendPrefsData GetBackendPrefs() const override; bool CheckVariationFontSupport() override; private: virtual void GetPlatformCMSOutputProfile(void* &mem, size_t &size) override; // read in the pref value for the lower threshold on font anti-aliasing static uint32_t ReadAntiAliasingThreshold();
--- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -434,17 +434,17 @@ gfxWindowsPlatform::HandleDeviceReset() InitializeConfig(); InitializeDevices(); UpdateANGLEConfig(); return true; } BackendPrefsData -gfxWindowsPlatform::GetBackendPrefs() +gfxWindowsPlatform::GetBackendPrefs() const { BackendPrefsData data; data.mCanvasBitmask = BackendTypeBit(BackendType::CAIRO) | BackendTypeBit(BackendType::SKIA); data.mContentBitmask = BackendTypeBit(BackendType::CAIRO) | BackendTypeBit(BackendType::SKIA); data.mCanvasDefault = BackendType::SKIA;
--- a/gfx/thebes/gfxWindowsPlatform.h +++ b/gfx/thebes/gfxWindowsPlatform.h @@ -228,17 +228,17 @@ protected: } void GetAcceleratedCompositorBackends(nsTArray<mozilla::layers::LayersBackend>& aBackends) override; virtual void GetPlatformCMSOutputProfile(void* &mem, size_t &size) override; void ImportGPUDeviceData(const mozilla::gfx::GPUDeviceData& aData) override; void ImportContentDeviceData(const mozilla::gfx::ContentDeviceData& aData) override; void BuildContentDeviceData(mozilla::gfx::ContentDeviceData* aOut) override; - BackendPrefsData GetBackendPrefs() override; + BackendPrefsData GetBackendPrefs() const override; bool CheckVariationFontSupport() override; protected: RenderMode mRenderMode; private: void Init();
--- a/js/src/gc/GC.cpp +++ b/js/src/gc/GC.cpp @@ -1069,30 +1069,18 @@ static const mozilla::EnumSet<ZealMode> ZealMode::YieldBeforeSweepingShapeTrees }; void GCRuntime::setZeal(uint8_t zeal, uint32_t frequency) { MOZ_ASSERT(zeal <= unsigned(ZealMode::Limit)); -#ifdef ENABLE_WASM_GC - // If we run with wasm-gc enabled and there's wasm frames on the stack, - // then GCs are suppressed and we should not allow to set the GC zeal, - // which presupposes that GC can be run right away. - // TODO (bug 1456824) This is temporary and should be removed once proper - // GC support is implemented. - JSContext* cx = rt->mainContextFromOwnThread(); - if (cx->options().wasmGc()) { - for (FrameIter iter(cx); !iter.done(); ++iter) { - if (iter.isWasm()) - return; - } - } -#endif + if (temporaryAbortIfWasmGc(rt->mainContextFromOwnThread())) + return; if (verifyPreData) VerifyBarriers(rt, PreBarrierVerifier); if (zeal == 0) { if (hasZealMode(ZealMode::GenerationalGC)) { evictNursery(JS::gcreason::DEBUG_GC); nursery().leaveZealMode(); @@ -8240,16 +8228,23 @@ GCRuntime::clearSelectedForMarking() void GCRuntime::setDeterministic(bool enabled) { MOZ_ASSERT(!JS::CurrentThreadIsHeapMajorCollecting()); deterministicOnly = enabled; } #endif +#ifdef ENABLE_WASM_GC +/* static */ bool +GCRuntime::temporaryAbortIfWasmGc(JSContext* cx) { + return cx->options().wasmGc() && cx->suppressGC; +} +#endif + #ifdef DEBUG /* Should only be called manually under gdb */ void PreventGCDuringInteractiveDebug() { TlsContext.get()->suppressGC++; }
--- a/js/src/gc/GCRuntime.h +++ b/js/src/gc/GCRuntime.h @@ -282,16 +282,26 @@ class GCRuntime void setNextScheduled(uint32_t count); void verifyPreBarriers(); void maybeVerifyPreBarriers(bool always); bool selectForMarking(JSObject* object); void clearSelectedForMarking(); void setDeterministic(bool enable); #endif +#ifdef ENABLE_WASM_GC + // If we run with wasm-gc enabled and there's wasm frames on the stack, + // then GCs are suppressed and many APIs should not be available. + // TODO (bug 1456824) This is temporary and should be removed once proper + // GC support is implemented. + static bool temporaryAbortIfWasmGc(JSContext* cx); +#else + static bool temporaryAbortIfWasmGc(JSContext* cx) { return false; } +#endif + uint64_t nextCellUniqueId() { MOZ_ASSERT(nextCellUniqueId_ > 0); uint64_t uid = ++nextCellUniqueId_; return uid; } #ifdef DEBUG bool shutdownCollectedEverything() const {
--- a/js/src/gc/Verifier.cpp +++ b/js/src/gc/Verifier.cpp @@ -174,30 +174,33 @@ NextNode(VerifyNode* node) } void gc::GCRuntime::startVerifyPreBarriers() { if (verifyPreData || isIncrementalGCInProgress()) return; + JSContext* cx = rt->mainContextFromOwnThread(); + if (temporaryAbortIfWasmGc(cx)) + return; + if (IsIncrementalGCUnsafe(rt) != AbortReason::None || - rt->mainContextFromOwnThread()->keepAtoms || + cx->keepAtoms || rt->hasHelperThreadZones()) { return; } number++; VerifyPreTracer* trc = js_new<VerifyPreTracer>(rt); if (!trc) return; - JSContext* cx = rt->mainContextFromOwnThread(); AutoPrepareForTracing prep(cx); { AutoLockGC lock(cx->runtime()); for (auto chunk = allNonEmptyChunks(lock); !chunk.done(); chunk.next()) chunk->bitmap.clear(); }
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/wasm/gc/block-debugger-findscripts.js @@ -0,0 +1,29 @@ +if (!wasmGcEnabled()) { + quit(); +} + +wasmEvalText(` + (module + (import "global" "func" (result i32)) + (func (export "func_0") (result i32) + call 0 ;; calls the import, which is func #0 + ) + ) +`, { + global: { + func() { + var g = newGlobal(); + var dbg = new Debugger(g); + var caught = false; + try { + dbg.findScripts().filter(isWasm(g, isValidWasmURL, 2)); + } catch(e) { + caught = true; + assertEq(/temporarily unavailable/.test(e.toString()), true); + } + // When this assertion fails, it's time to remove the restriction in + // Debugger.findScripts. + assertEq(caught, true); + } + } +}).exports.func_0();;
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/wasm/gc/block-verifyprebarriers.js @@ -0,0 +1,14 @@ +wasmEvalText(` + (module + (import "global" "func" (result i32)) + (func (export "func_0") (result i32) + call 0 + ) + ) +`, { + global: { + func() { + verifyprebarriers(); + } + } +}).exports.func_0();
--- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -1281,18 +1281,21 @@ MConstant::valueToBoolean(bool* res) con return true; case MIRType::Symbol: *res = true; return true; case MIRType::String: *res = toString()->length() != 0; return true; case MIRType::Object: - *res = !EmulatesUndefined(&toObject()); - return true; + // We have to call EmulatesUndefined but that reads obj->group->clasp + // and so it's racy when the object has a lazy group. The main callers + // of this (MTest, MNot) already know how to fold the object case, so + // just give up. + return false; default: MOZ_ASSERT(IsMagicType(type())); return false; } } HashNumber MWasmFloatConstant::valueHash() const
--- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -1636,21 +1636,22 @@ class MConstant : public MNullaryInstruc static MConstant* NewFloat32(TempAllocator& alloc, double d); static MConstant* NewInt64(TempAllocator& alloc, int64_t i); static MConstant* NewConstraintlessObject(TempAllocator& alloc, JSObject* v); static MConstant* Copy(TempAllocator& alloc, MConstant* src) { return new(alloc) MConstant(*src); } // Try to convert this constant to boolean, similar to js::ToBoolean. - // Returns false if the type is MIRType::Magic*. + // Returns false if the type is MIRType::Magic* or MIRType::Object. bool MOZ_MUST_USE valueToBoolean(bool* res) const; // Like valueToBoolean, but returns the result directly instead of using - // an outparam. Should not be used if this constant might be a magic value. + // an outparam. Should not be used if this constant might be a magic value + // or an object. bool valueToBooleanInfallible() const { bool res; MOZ_ALWAYS_TRUE(valueToBoolean(&res)); return res; } #ifdef JS_JITSPEW void printOpcode(GenericPrinter& out) const override;
--- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -4697,16 +4697,21 @@ class MOZ_STACK_CLASS Debugger::ScriptQu } }; /* static */ bool Debugger::findScripts(JSContext* cx, unsigned argc, Value* vp) { THIS_DEBUGGER(cx, argc, vp, "findScripts", args, dbg); + if (gc::GCRuntime::temporaryAbortIfWasmGc(cx)) { + JS_ReportErrorASCII(cx, "API temporarily unavailable under wasm gc"); + return false; + } + ScriptQuery query(cx, dbg); if (!query.init()) return false; if (args.length() >= 1) { RootedObject queryObject(cx, NonNullObject(cx, args[0])); if (!queryObject || !query.parseQuery(queryObject)) return false;
--- a/js/src/vm/ObjectGroup.h +++ b/js/src/vm/ObjectGroup.h @@ -250,23 +250,23 @@ class ObjectGroup : public gc::TenuredCe maybePreliminaryObjectsDontCheckGeneration(); } inline UnboxedLayout* maybeUnboxedLayout(const AutoSweepObjectGroup& sweep); inline UnboxedLayout& unboxedLayout(const AutoSweepObjectGroup& sweep); UnboxedLayout* maybeUnboxedLayoutDontCheckGeneration() const { if (addendumKind() == Addendum_UnboxedLayout) - return reinterpret_cast<UnboxedLayout*>(addendum_); + return &unboxedLayoutDontCheckGeneration(); return nullptr; } UnboxedLayout& unboxedLayoutDontCheckGeneration() const { MOZ_ASSERT(addendumKind() == Addendum_UnboxedLayout); - return *maybeUnboxedLayoutDontCheckGeneration(); + return *reinterpret_cast<UnboxedLayout*>(addendum_); } void setUnboxedLayout(UnboxedLayout* layout) { setAddendum(Addendum_UnboxedLayout, layout); } ObjectGroup* maybeOriginalUnboxedGroup() const { if (addendumKind() == Addendum_OriginalUnboxedGroup) @@ -277,23 +277,23 @@ class ObjectGroup : public gc::TenuredCe void setOriginalUnboxedGroup(ObjectGroup* group) { setAddendum(Addendum_OriginalUnboxedGroup, group); } TypeDescr* maybeTypeDescr() { // Note: there is no need to sweep when accessing the type descriptor // of an object, as it is strongly held and immutable. if (addendumKind() == Addendum_TypeDescr) - return reinterpret_cast<TypeDescr*>(addendum_); + return &typeDescr(); return nullptr; } TypeDescr& typeDescr() { MOZ_ASSERT(addendumKind() == Addendum_TypeDescr); - return *maybeTypeDescr(); + return *reinterpret_cast<TypeDescr*>(addendum_); } void setTypeDescr(TypeDescr* descr) { setAddendum(Addendum_TypeDescr, descr); } JSFunction* maybeInterpretedFunction() { // Note: as with type descriptors, there is no need to sweep when
--- a/js/src/vm/StructuredClone.cpp +++ b/js/src/vm/StructuredClone.cpp @@ -2401,22 +2401,19 @@ JSStructuredCloneReader::readHeader() if (storedScope < JS::StructuredCloneScope::SameProcessSameThread || storedScope > JS::StructuredCloneScope::DifferentProcessForIndexedDB) { JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr, JSMSG_SC_BAD_SERIALIZED_DATA, "invalid structured clone scope"); return false; } - if (storedScope == JS::StructuredCloneScope::SameProcessSameThread && - allowedScope == JS::StructuredCloneScope::DifferentProcessForIndexedDB) - { - // Bug 1434308 - allow stored IndexedDB clones to contain what is - // essentially DifferentProcess data, but labeled as - // SameProcessSameThread (because that's what old code wrote.) + if (allowedScope == JS::StructuredCloneScope::DifferentProcessForIndexedDB) { + // Bug 1434308 and bug 1458320 - the scopes stored in old IndexedDB + // clones are incorrect. Treat them as if they were DifferentProcess. allowedScope = JS::StructuredCloneScope::DifferentProcess; return true; } if (storedScope < allowedScope) { JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr, JSMSG_SC_BAD_SERIALIZED_DATA, "incompatible structured clone scope");
--- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -11501,23 +11501,16 @@ nsAdaptorPrintReason(ReflowInput& aReflo reflowReasonString = "unknown"; break; } printf("%s",reflowReasonString); } #endif -#ifdef DEBUG_LAYOUT -void -nsFrame::GetBoxName(nsAutoString& aName) -{ - GetFrameName(aName); -} -#endif #ifdef DEBUG static void GetTagName(nsFrame* aFrame, nsIContent* aContent, int aResultSize, char* aResult) { if (aContent) { snprintf(aResult, aResultSize, "%s@%p",
--- a/layout/generic/nsFrame.h +++ b/layout/generic/nsFrame.h @@ -674,20 +674,16 @@ protected: int32_t* aContentOffset, int32_t* aTarget); // Fills aCursor with the appropriate information from ui static void FillCursorInformationFromStyle(const nsStyleUserInterface* ui, nsIFrame::Cursor& aCursor); NS_IMETHOD DoXULLayout(nsBoxLayoutState& aBoxLayoutState) override; -#ifdef DEBUG_LAYOUT - void GetBoxName(nsAutoString& aName) override; -#endif - nsBoxLayoutMetrics* BoxMetrics() const; // Fire DOM event. If no aContent argument use frame's mContent. void FireDOMEvent(const nsAString& aDOMEventName, nsIContent *aContent = nullptr); private: void BoxReflow(nsBoxLayoutState& aState, nsPresContext* aPresContext,
--- a/layout/generic/nsFrameStateBits.h +++ b/layout/generic/nsFrameStateBits.h @@ -294,19 +294,17 @@ FRAME_STATE_BIT(Generic, 59, NS_FRAME_IS FRAME_STATE_GROUP(Box, nsBoxFrame) FRAME_STATE_BIT(Box, 20, NS_STATE_BOX_CHILD_RESERVED) FRAME_STATE_BIT(Box, 21, NS_STATE_STACK_NOT_POSITIONED) FRAME_STATE_BIT(Box, 22, NS_STATE_IS_HORIZONTAL) FRAME_STATE_BIT(Box, 23, NS_STATE_AUTO_STRETCH) FRAME_STATE_BIT(Box, 24, NS_STATE_IS_ROOT) -FRAME_STATE_BIT(Box, 25, NS_STATE_CURRENTLY_IN_DEBUG) -FRAME_STATE_BIT(Box, 26, NS_STATE_SET_TO_DEBUG) -FRAME_STATE_BIT(Box, 27, NS_STATE_DEBUG_WAS_SET) +/* Bits 25, 26, and 27 were used for xul debug flags but are now unused */ FRAME_STATE_BIT(Box, 28, NS_STATE_MENU_HAS_POPUP_LIST) FRAME_STATE_BIT(Box, 29, NS_STATE_BOX_WRAPS_KIDS_IN_BLOCK) FRAME_STATE_BIT(Box, 30, NS_STATE_EQUAL_SIZE) FRAME_STATE_BIT(Box, 31, NS_STATE_IS_DIRECTION_NORMAL) FRAME_STATE_BIT(Box, 60, NS_FRAME_MOUSE_THROUGH_ALWAYS) FRAME_STATE_BIT(Box, 61, NS_FRAME_MOUSE_THROUGH_NEVER)
--- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -1568,20 +1568,16 @@ nsXULScrollFrame::GetXULBoxAscent(nsBoxL ascent += m.top; return ascent; } nsSize nsXULScrollFrame::GetXULPrefSize(nsBoxLayoutState& aState) { -#ifdef DEBUG_LAYOUT - PropagateDebug(aState); -#endif - nsSize pref = mHelper.mScrolledFrame->GetXULPrefSize(aState); ScrollbarStyles styles = GetScrollbarStyles(); // scrolled frames don't have their own margins if (mHelper.mVScrollbarBox && styles.mVertical == NS_STYLE_OVERFLOW_SCROLL) { @@ -1601,20 +1597,16 @@ nsXULScrollFrame::GetXULPrefSize(nsBoxLa bool widthSet, heightSet; nsIFrame::AddXULPrefSize(this, pref, widthSet, heightSet); return pref; } nsSize nsXULScrollFrame::GetXULMinSize(nsBoxLayoutState& aState) { -#ifdef DEBUG_LAYOUT - PropagateDebug(aState); -#endif - nsSize min = mHelper.mScrolledFrame->GetXULMinSizeForScrollArea(aState); ScrollbarStyles styles = GetScrollbarStyles(); if (mHelper.mVScrollbarBox && styles.mVertical == NS_STYLE_OVERFLOW_SCROLL) { nsSize vSize = mHelper.mVScrollbarBox->GetXULMinSize(aState); AddMargin(mHelper.mVScrollbarBox, vSize); @@ -1636,20 +1628,16 @@ nsXULScrollFrame::GetXULMinSize(nsBoxLay bool widthSet, heightSet; nsIFrame::AddXULMinSize(aState, this, min, widthSet, heightSet); return min; } nsSize nsXULScrollFrame::GetXULMaxSize(nsBoxLayoutState& aState) { -#ifdef DEBUG_LAYOUT - PropagateDebug(aState); -#endif - nsSize maxSize(NS_INTRINSICSIZE, NS_INTRINSICSIZE); AddBorderAndPadding(maxSize); bool widthSet, heightSet; nsIFrame::AddXULMaxSize(this, maxSize, widthSet, heightSet); return maxSize; }
--- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -3740,23 +3740,16 @@ public: virtual Halignment GetXULHAlign() const = 0; bool IsXULHorizontal() const { return (mState & NS_STATE_IS_HORIZONTAL) != 0; } bool IsXULNormalDirection() const { return (mState & NS_STATE_IS_DIRECTION_NORMAL) != 0; } nsresult XULRedraw(nsBoxLayoutState& aState); virtual nsresult XULRelayoutChildAtOrdinal(nsIFrame* aChild)=0; -#ifdef DEBUG_LAYOUT - virtual nsresult SetXULDebug(nsBoxLayoutState& aState, bool aDebug)=0; - virtual nsresult GetXULDebug(bool& aDebug)=0; - - virtual nsresult XULDumpBox(FILE* out)=0; -#endif - static bool AddXULPrefSize(nsIFrame* aBox, nsSize& aSize, bool& aWidth, bool& aHeightSet); static bool AddXULMinSize(nsBoxLayoutState& aState, nsIFrame* aBox, nsSize& aSize, bool& aWidth, bool& aHeightSet); static bool AddXULMaxSize(nsIFrame* aBox, nsSize& aSize, bool& aWidth, bool& aHeightSet); static bool AddXULFlex(nsIFrame* aBox, nscoord& aFlex); // END OF BOX LAYOUT METHODS // The above methods have been migrated from nsIBox and are in the process of
--- a/layout/style/nsDOMCSSAttrDeclaration.cpp +++ b/layout/style/nsDOMCSSAttrDeclaration.cpp @@ -13,16 +13,17 @@ #include "mozilla/dom/Element.h" #include "mozilla/dom/MutationEventBinding.h" #include "mozilla/InternalMutationEvent.h" #include "mozilla/ServoDeclarationBlock.h" #include "nsContentUtils.h" #include "nsIDocument.h" #include "nsIURI.h" #include "nsNodeUtils.h" +#include "nsSMILCSSValueType.h" #include "nsWrapperCacheInlines.h" #include "nsIFrame.h" #include "ActiveLayerTracker.h" using namespace mozilla; nsDOMCSSAttributeDeclaration::nsDOMCSSAttributeDeclaration(dom::Element* aElement, bool aIsSMILOverride) @@ -175,26 +176,34 @@ nsDOMCSSAttributeDeclaration::GetServoCS { return { mElement->GetURLDataForStyleAttr(aSubjectPrincipal), mElement->OwnerDoc()->GetCompatibilityMode(), mElement->OwnerDoc()->CSSLoader(), }; } -css::Rule* -nsDOMCSSAttributeDeclaration::GetParentRule() +nsresult +nsDOMCSSAttributeDeclaration::SetSMILValue(const nsCSSPropertyID aPropID, + const nsSMILValue& aValue) { - return nullptr; -} + MOZ_ASSERT(mIsSMILOverride); -/* virtual */ nsINode* -nsDOMCSSAttributeDeclaration::GetParentObject() -{ - return mElement; + // Convert nsSMILValue to string. + // + // FIXME(emilio): This roundtrip should go away. + nsAutoString valStr; + nsSMILCSSValueType::ValueToString(aValue, valStr); + + nsAutoString oldValStr; + GetPropertyValue(aPropID, oldValStr); + if (valStr.Equals(oldValStr)) { + return NS_OK; + } + return SetPropertyValue(aPropID, valStr, nullptr); } nsresult nsDOMCSSAttributeDeclaration::SetPropertyValue(const nsCSSPropertyID aPropID, const nsAString& aValue, nsIPrincipal* aSubjectPrincipal) { // Scripted modifications to style.opacity or style.transform
--- a/layout/style/nsDOMCSSAttrDeclaration.h +++ b/layout/style/nsDOMCSSAttrDeclaration.h @@ -9,16 +9,17 @@ #ifndef nsDOMCSSAttributeDeclaration_h #define nsDOMCSSAttributeDeclaration_h #include "mozilla/Attributes.h" #include "mozilla/dom/DocGroup.h" #include "nsDOMCSSDeclaration.h" +class nsSMILValue; namespace mozilla { namespace dom { class DomGroup; class Element; } // namespace dom } // namespace mozilla class nsDOMCSSAttributeDeclaration final : public nsDOMCSSDeclaration @@ -33,19 +34,27 @@ public: // If GetCSSDeclaration returns non-null, then the decl it returns // is owned by our current style rule. virtual mozilla::DeclarationBlock* GetCSSDeclaration(Operation aOperation) override; virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv, nsIPrincipal* aSubjectPrincipal) override; nsDOMCSSDeclaration::ServoCSSParsingEnvironment GetServoCSSParsingEnvironment(nsIPrincipal* aSubjectPrincipal) const final; - mozilla::css::Rule* GetParentRule() override; + mozilla::css::Rule* GetParentRule() override + { + return nullptr; + } - virtual nsINode* GetParentObject() override; + nsINode* GetParentObject() override + { + return mElement; + } + + nsresult SetSMILValue(const nsCSSPropertyID aPropID, const nsSMILValue&); nsresult SetPropertyValue(const nsCSSPropertyID aPropID, const nsAString& aValue, nsIPrincipal* aSubjectPrincipal) override; protected: ~nsDOMCSSAttributeDeclaration();
--- a/layout/style/nsDOMCSSDeclaration.cpp +++ b/layout/style/nsDOMCSSDeclaration.cpp @@ -18,19 +18,17 @@ #include "nsIURI.h" #include "mozilla/dom/BindingUtils.h" #include "nsContentUtils.h" #include "nsQueryObject.h" #include "mozilla/layers/ScrollLinkedEffectDetector.h" using namespace mozilla; -nsDOMCSSDeclaration::~nsDOMCSSDeclaration() -{ -} +nsDOMCSSDeclaration::~nsDOMCSSDeclaration() = default; /* virtual */ JSObject* nsDOMCSSDeclaration::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) { return dom::CSS2PropertiesBinding::Wrap(aCx, this, aGivenProto); } NS_IMPL_QUERY_INTERFACE(nsDOMCSSDeclaration, @@ -265,43 +263,42 @@ nsDOMCSSDeclaration::GetServoCSSParsingE return { sheet->URLData(), eCompatibility_FullStandards, nullptr, }; } -template<typename GeckoFunc, typename ServoFunc> +template<typename Func> nsresult nsDOMCSSDeclaration::ModifyDeclaration(nsIPrincipal* aSubjectPrincipal, - GeckoFunc aGeckoFunc, - ServoFunc aServoFunc) + Func aFunc) { DeclarationBlock* olddecl = GetCSSDeclaration(eOperation_Modify); if (!olddecl) { return NS_ERROR_NOT_AVAILABLE; } // For nsDOMCSSAttributeDeclaration, SetCSSDeclaration will lead to // Attribute setting code, which leads in turn to BeginUpdate. We // need to start the update now so that the old rule doesn't get used // between when we mutate the declaration and when we set the new // rule (see stack in bug 209575). mozAutoDocConditionalContentUpdateBatch autoUpdate(DocToUpdate(), true); RefPtr<DeclarationBlock> decl = olddecl->EnsureMutable(); bool changed; - ServoCSSParsingEnvironment servoEnv = GetServoCSSParsingEnvironment( - aSubjectPrincipal); + ServoCSSParsingEnvironment servoEnv = + GetServoCSSParsingEnvironment(aSubjectPrincipal); if (!servoEnv.mUrlExtraData) { return NS_ERROR_NOT_AVAILABLE; } - changed = aServoFunc(decl->AsServo(), servoEnv); + changed = aFunc(decl->AsServo(), servoEnv); if (!changed) { // Parsing failed -- but we don't throw an exception for that. return NS_OK; } return SetCSSDeclaration(decl); } @@ -309,19 +306,16 @@ nsDOMCSSDeclaration::ModifyDeclaration(n nsresult nsDOMCSSDeclaration::ParsePropertyValue(const nsCSSPropertyID aPropID, const nsAString& aPropValue, bool aIsImportant, nsIPrincipal* aSubjectPrincipal) { return ModifyDeclaration( aSubjectPrincipal, - [&](css::Declaration* decl, CSSParsingEnvironment& env, bool* changed) { - MOZ_CRASH("old style system disabled"); - }, [&](ServoDeclarationBlock* decl, ServoCSSParsingEnvironment& env) { NS_ConvertUTF16toUTF8 value(aPropValue); return Servo_DeclarationBlock_SetPropertyById( decl->Raw(), aPropID, &value, aIsImportant, env.mUrlExtraData, ParsingMode::Default, env.mCompatMode, env.mLoader); }); } @@ -329,19 +323,16 @@ nsresult nsDOMCSSDeclaration::ParseCustomPropertyValue(const nsAString& aPropertyName, const nsAString& aPropValue, bool aIsImportant, nsIPrincipal* aSubjectPrincipal) { MOZ_ASSERT(nsCSSProps::IsCustomPropertyName(aPropertyName)); return ModifyDeclaration( aSubjectPrincipal, - [&](css::Declaration* decl, CSSParsingEnvironment& env, bool* changed) { - MOZ_CRASH("old style system disabled"); - }, [&](ServoDeclarationBlock* decl, ServoCSSParsingEnvironment& env) { NS_ConvertUTF16toUTF8 property(aPropertyName); NS_ConvertUTF16toUTF8 value(aPropValue); return Servo_DeclarationBlock_SetProperty( decl->Raw(), &property, &value, aIsImportant, env.mUrlExtraData, ParsingMode::Default, env.mCompatMode, env.mLoader); }); }
--- a/layout/style/nsDOMCSSDeclaration.h +++ b/layout/style/nsDOMCSSDeclaration.h @@ -223,14 +223,14 @@ protected: nsresult RemovePropertyInternal(nsCSSPropertyID aPropID); nsresult RemovePropertyInternal(const nsAString& aProperty); protected: virtual ~nsDOMCSSDeclaration(); private: - template<typename GeckoFunc, typename ServoFunc> + template<typename ServoFunc> inline nsresult ModifyDeclaration(nsIPrincipal* aSubjectPrincipal, - GeckoFunc aGeckoFunc, ServoFunc aServoFunc); + ServoFunc aServoFunc); }; #endif // nsDOMCSSDeclaration_h___
--- a/layout/xul/nsBox.cpp +++ b/layout/xul/nsBox.cpp @@ -20,118 +20,19 @@ #include "nsBoxLayout.h" #include "FrameLayerBuilder.h" #include "mozilla/dom/Attr.h" #include "mozilla/dom/Element.h" #include <algorithm> using namespace mozilla; -#ifdef DEBUG_LAYOUT -int32_t gIndent = 0; -#endif - -#ifdef DEBUG_LAYOUT -void -nsBoxAddIndents() -{ - for(int32_t i=0; i < gIndent; i++) - { - printf(" "); - } -} -#endif - -#ifdef DEBUG_LAYOUT -void -nsBox::AppendAttribute(const nsAutoString& aAttribute, const nsAutoString& aValue, nsAutoString& aResult) -{ - aResult.Append(aAttribute); - aResult.AppendLiteral("='"); - aResult.Append(aValue); - aResult.AppendLiteral("' "); -} - -void -nsBox::ListBox(nsAutoString& aResult) -{ - nsAutoString name; - GetBoxName(name); - - char addr[100]; - sprintf(addr, "[@%p] ", static_cast<void*>(this)); - - aResult.AppendASCII(addr); - aResult.Append(name); - aResult.Append(' '); - - nsIContent* content = GetContent(); - - // add on all the set attributes - if (content && content->IsElement()) { - RefPtr<nsDOMAttributeMap> namedMap = content->AsElement()->Attributes(); - - uint32_t length = namedMap->Length(); - - RefPtr<dom::Attr> attribute; - for (uint32_t i = 0; i < length; ++i) - { - attribute = namedMap->Item(i); - attribute->GetName(name); - nsAutoString value; - attribute->GetValue(value); - AppendAttribute(name, value, aResult); - } - } -} - -nsresult -nsBox::XULDumpBox(FILE* aFile) -{ - nsAutoString s; - ListBox(s); - fprintf(aFile, "%s", NS_LossyConvertUTF16toASCII(s).get()); - return NS_OK; -} - -void -nsBox::PropagateDebug(nsBoxLayoutState& aState) -{ - // propagate debug information - if (mState & NS_STATE_DEBUG_WAS_SET) { - if (mState & NS_STATE_SET_TO_DEBUG) - SetXULDebug(aState, true); - else - SetXULDebug(aState, false); - } else if (mState & NS_STATE_IS_ROOT) { - SetXULDebug(aState, gDebug); - } -} -#endif - -#ifdef DEBUG_LAYOUT -void -nsBox::GetBoxName(nsAutoString& aName) -{ - aName.AssignLiteral("Box"); -} -#endif - nsresult nsBox::BeginXULLayout(nsBoxLayoutState& aState) { -#ifdef DEBUG_LAYOUT - - nsBoxAddIndents(); - printf("XULLayout: "); - XULDumpBox(stdout); - printf("\n"); - gIndent++; -#endif - // mark ourselves as dirty so no child under us // can post an incremental layout. // XXXldb Is this still needed? AddStateBits(NS_FRAME_HAS_DIRTY_CHILDREN); if (GetStateBits() & NS_FRAME_IS_DIRTY) { // If the parent is dirty, all the children are dirty (ReflowInput @@ -142,49 +43,38 @@ nsBox::BeginXULLayout(nsBoxLayoutState& } // Another copy-over from ReflowInput. // Since we are in reflow, we don't need to store these properties anymore. DeleteProperty(UsedBorderProperty()); DeleteProperty(UsedPaddingProperty()); DeleteProperty(UsedMarginProperty()); -#ifdef DEBUG_LAYOUT - PropagateDebug(aState); -#endif - return NS_OK; } NS_IMETHODIMP nsBox::DoXULLayout(nsBoxLayoutState& aState) { return NS_OK; } nsresult nsBox::EndXULLayout(nsBoxLayoutState& aState) { - - #ifdef DEBUG_LAYOUT - --gIndent; - #endif - return SyncLayout(aState); } bool nsBox::gGotTheme = false; nsITheme* nsBox::gTheme = nullptr; nsBox::nsBox(ClassID aID) : nsIFrame(aID) { MOZ_COUNT_CTOR(nsBox); - //mX = 0; - //mY = 0; if (!gGotTheme) { gGotTheme = true; CallGetService("@mozilla.org/chrome/chrome-native-theme;1", &gTheme); } } nsBox::~nsBox() { @@ -218,26 +108,22 @@ nsIFrame::GetXULClientRect(nsRect& aClie aClientRect.Deflate(borderPadding); if (aClientRect.width < 0) aClientRect.width = 0; if (aClientRect.height < 0) aClientRect.height = 0; - // NS_ASSERTION(aClientRect.width >=0 && aClientRect.height >= 0, "Content Size < 0"); - return NS_OK; } void nsBox::SetXULBounds(nsBoxLayoutState& aState, const nsRect& aRect, bool aRemoveOverflowAreas) { - NS_BOX_ASSERTION(this, aRect.width >=0 && aRect.height >= 0, "SetXULBounds Size < 0"); - nsRect rect(mRect); uint32_t flags = GetXULLayoutFlags(); uint32_t stateFlags = aState.LayoutFlags(); flags |= stateFlags; @@ -254,29 +140,16 @@ nsBox::SetXULBounds(nsBoxLayoutState& aS } if (!(flags & NS_FRAME_NO_MOVE_VIEW)) { nsContainerFrame::PositionFrameView(this); if ((rect.x != aRect.x) || (rect.y != aRect.y)) nsContainerFrame::PositionChildViews(this); } - - - /* - // only if the origin changed - if ((rect.x != aRect.x) || (rect.y != aRect.y)) { - if (frame->HasView()) { - nsContainerFrame::PositionFrameView(presContext, frame, - frame->GetView()); - } else { - nsContainerFrame::PositionChildViews(presContext, frame); - } - } - */ } nsresult nsIFrame::GetXULBorderAndPadding(nsMargin& aBorderAndPadding) { aBorderAndPadding.SizeTo(0, 0, 0, 0); nsresult rv = GetXULBorder(aBorderAndPadding); if (NS_FAILED(rv)) @@ -928,53 +801,8 @@ nsBox::GetNextXULBox(const nsIFrame* aFr /*static*/ nsIFrame* nsBox::GetParentXULBox(const nsIFrame* aFrame) { return aFrame->GetParent() && aFrame->GetParent()->IsXULBoxFrame() ? aFrame->GetParent() : nullptr; } -#ifdef DEBUG_LAYOUT -nsresult -nsBox::SetXULDebug(nsBoxLayoutState& aState, bool aDebug) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsBox::GetDebugBoxAt( const nsPoint& aPoint, - nsIFrame** aBox) -{ - nsRect thisRect(nsPoint(0,0), GetSize()); - if (!thisRect.Contains(aPoint)) - return NS_ERROR_FAILURE; - - nsIFrame* child = nsBox::GetChildXULBox(this); - nsIFrame* hit = nullptr; - - *aBox = nullptr; - while (nullptr != child) { - nsresult rv = child->GetDebugBoxAt(aPoint - child->GetOffsetTo(this), &hit); - - if (NS_SUCCEEDED(rv) && hit) { - *aBox = hit; - } - child = GetNextXULBox(child); - } - - // found a child - if (*aBox) { - return NS_OK; - } - - return NS_ERROR_FAILURE; -} - - -nsresult -nsBox::GetXULDebug(bool& aDebug) -{ - aDebug = false; - return NS_OK; -} - -#endif
--- a/layout/xul/nsBox.h +++ b/layout/xul/nsBox.h @@ -37,31 +37,21 @@ public: virtual nsresult GetXULPadding(nsMargin& aBorderAndPadding) override; virtual nsresult GetXULMargin(nsMargin& aMargin) override; virtual Valignment GetXULVAlign() const override { return vAlign_Top; } virtual Halignment GetXULHAlign() const override { return hAlign_Left; } virtual nsresult XULRelayoutChildAtOrdinal(nsIFrame* aChild) override; -#ifdef DEBUG_LAYOUT - NS_IMETHOD GetDebugBoxAt(const nsPoint& aPoint, nsIFrame** aBox) override; - virtual nsresult GetXULDebug(bool& aDebug) override; - virtual nsresult SetXULDebug(nsBoxLayoutState& aState, bool aDebug) override; - - virtual nsresult XULDumpBox(FILE* out) override; - void PropagateDebug(nsBoxLayoutState& aState); -#endif - nsBox(ClassID aID); virtual ~nsBox(); /** - * Returns true if this box clips its children, e.g., if this box is an sc -rollbox. + * Returns true if this box clips its children, e.g., if this box is an scrollbox. */ virtual bool DoesClipChildren(); virtual bool ComputesOwnOverflowArea() = 0; nsresult SyncLayout(nsBoxLayoutState& aBoxLayoutState); bool DoesNeedRecalc(const nsSize& aSize); bool DoesNeedRecalc(nscoord aCoord); @@ -79,50 +69,24 @@ rollbox. static nscoord BoundsCheck(nscoord aMinSize, nscoord aPrefSize, nscoord aMaxSize); static nsIFrame* GetChildXULBox(const nsIFrame* aFrame); static nsIFrame* GetNextXULBox(const nsIFrame* aFrame); static nsIFrame* GetParentXULBox(const nsIFrame* aFrame); protected: -#ifdef DEBUG_LAYOUT - virtual void AppendAttribute(const nsAutoString& aAttribute, const nsAutoString& aValue, nsAutoString& aResult); - - virtual void ListBox(nsAutoString& aResult); -#endif - nsresult BeginXULLayout(nsBoxLayoutState& aState); NS_IMETHOD DoXULLayout(nsBoxLayoutState& aBoxLayoutState); nsresult EndXULLayout(nsBoxLayoutState& aState); -#ifdef DEBUG_LAYOUT - virtual void GetBoxName(nsAutoString& aName); - void PropagateDebug(nsBoxLayoutState& aState); -#endif - static bool gGotTheme; static nsITheme* gTheme; enum eMouseThrough { unset, never, always }; - -private: - - //nscoord mX; - //nscoord mY; }; -#ifdef DEBUG_LAYOUT -#define NS_BOX_ASSERTION(box,expr,str) \ - if (!(expr)) { \ - box->XULDumpBox(stdout); \ - NS_DebugBreak(NSDebugAssertion, str, #expr, __FILE__, __LINE__); \ - } -#else -#define NS_BOX_ASSERTION(box,expr,str) {} -#endif - #endif
--- a/layout/xul/nsBoxFrame.cpp +++ b/layout/xul/nsBoxFrame.cpp @@ -71,33 +71,16 @@ #include "nsIURI.h" #include "mozilla/TouchEvents.h" using namespace mozilla; using namespace mozilla::dom; using namespace mozilla::gfx; -//define DEBUG_REDRAW - -#define DEBUG_SPRING_SIZE 8 -#define DEBUG_BORDER_SIZE 2 -#define COIL_SIZE 8 - -//#define TEST_SANITY - -#ifdef DEBUG_rods -//#define DO_NOISY_REFLOW -#endif - -#ifdef DEBUG_LAYOUT -bool nsBoxFrame::gDebug = false; -nsIFrame* nsBoxFrame::mDebugChild = nullptr; -#endif - nsIFrame* NS_NewBoxFrame(nsIPresShell* aPresShell, ComputedStyle* aStyle, bool aIsRoot, nsBoxLayout* aLayoutManager) { return new (aPresShell) nsBoxFrame(aStyle, nsBoxFrame::kClassID, aIsRoot, aLayoutManager); } nsIFrame* @@ -181,23 +164,16 @@ nsBoxFrame::Init(nsIContent* aCont if (GetStateBits() & NS_FRAME_FONT_INFLATION_CONTAINER) { AddStateBits(NS_FRAME_FONT_INFLATION_FLOW_ROOT); } MarkIntrinsicISizesDirty(); CacheAttributes(); -#ifdef DEBUG_LAYOUT - // if we are root and this - if (mState & NS_STATE_IS_ROOT) { - GetDebugPref(); - } -#endif - UpdateMouseThrough(); // register access key RegUnregAccessKey(true); } void nsBoxFrame::UpdateMouseThrough() { @@ -252,53 +228,18 @@ nsBoxFrame::CacheAttributes() RemoveStateBits(NS_STATE_EQUAL_SIZE); bool autostretch = !!(mState & NS_STATE_AUTO_STRETCH); GetInitialAutoStretch(autostretch); if (autostretch) AddStateBits(NS_STATE_AUTO_STRETCH); else RemoveStateBits(NS_STATE_AUTO_STRETCH); - - -#ifdef DEBUG_LAYOUT - bool debug = mState & NS_STATE_SET_TO_DEBUG; - bool debugSet = GetInitialDebug(debug); - if (debugSet) { - AddStateBits(NS_STATE_DEBUG_WAS_SET); - if (debug) - AddStateBits(NS_STATE_SET_TO_DEBUG); - else - RemoveStateBits(NS_STATE_SET_TO_DEBUG); - } else { - RemoveStateBits(NS_STATE_DEBUG_WAS_SET); - } -#endif } -#ifdef DEBUG_LAYOUT -bool -nsBoxFrame::GetInitialDebug(bool& aDebug) -{ - if (!GetContent() || !GetContent()->IsElement()) - return false; - - static Element::AttrValuesArray strings[] = - {&nsGkAtoms::_false, &nsGkAtoms::_true, nullptr}; - int32_t index = GetContent()->FindAttrValueIn(kNameSpaceID_None, - nsGkAtoms::debug, strings, eCaseMatters); - if (index >= 0) { - aDebug = index == 1; - return true; - } - - return false; -} -#endif - bool nsBoxFrame::GetInitialHAlignment(nsBoxFrame::Halignment& aHalign) { if (!GetContent() || !GetContent()->IsElement()) return false; Element* element = GetContent()->AsElement(); // XXXdwh Everything inside this if statement is deprecated code. @@ -767,20 +708,16 @@ nsBoxFrame::GetXULPrefSize(nsBoxLayoutSt nsSize size(0,0); DISPLAY_PREF_SIZE(this, size); if (!DoesNeedRecalc(mPrefSize)) { size = mPrefSize; return size; } -#ifdef DEBUG_LAYOUT - PropagateDebug(aBoxLayoutState); -#endif - if (IsXULCollapsed()) return size; // if the size was not completely redefined in CSS then ask our children bool widthSet, heightSet; if (!nsIFrame::AddXULPrefSize(this, size, widthSet, heightSet)) { if (mLayoutManager) { @@ -803,20 +740,16 @@ nsBoxFrame::GetXULPrefSize(nsBoxLayoutSt } nscoord nsBoxFrame::GetXULBoxAscent(nsBoxLayoutState& aBoxLayoutState) { if (!DoesNeedRecalc(mAscent)) return mAscent; -#ifdef DEBUG_LAYOUT - PropagateDebug(aBoxLayoutState); -#endif - if (IsXULCollapsed()) return 0; if (mLayoutManager) mAscent = mLayoutManager->GetAscent(this, aBoxLayoutState); else mAscent = nsBox::GetXULBoxAscent(aBoxLayoutState); @@ -831,20 +764,16 @@ nsBoxFrame::GetXULMinSize(nsBoxLayoutSta nsSize size(0,0); DISPLAY_MIN_SIZE(this, size); if (!DoesNeedRecalc(mMinSize)) { size = mMinSize; return size; } -#ifdef DEBUG_LAYOUT - PropagateDebug(aBoxLayoutState); -#endif - if (IsXULCollapsed()) return size; // if the size was not completely redefined in CSS then ask our children bool widthSet, heightSet; if (!nsIFrame::AddXULMinSize(aBoxLayoutState, this, size, widthSet, heightSet)) { if (mLayoutManager) { @@ -872,20 +801,16 @@ nsBoxFrame::GetXULMaxSize(nsBoxLayoutSta nsSize size(NS_INTRINSICSIZE, NS_INTRINSICSIZE); DISPLAY_MAX_SIZE(this, size); if (!DoesNeedRecalc(mMaxSize)) { size = mMaxSize; return size; } -#ifdef DEBUG_LAYOUT - PropagateDebug(aBoxLayoutState); -#endif - if (IsXULCollapsed()) return size; // if the size was not completely redefined in CSS then ask our children bool widthSet, heightSet; if (!nsIFrame::AddXULMaxSize(this, size, widthSet, heightSet)) { if (mLayoutManager) { @@ -977,42 +902,16 @@ nsBoxFrame::DestroyFrom(nsIFrame* aDestr RegUnregAccessKey(false); // clean up the container box's layout manager and child boxes SetXULLayoutManager(nullptr); nsContainerFrame::DestroyFrom(aDestructRoot, aPostDestroyData); } -#ifdef DEBUG_LAYOUT -nsresult -nsBoxFrame::SetXULDebug(nsBoxLayoutState& aState, bool aDebug) -{ - // see if our state matches the given debug state - bool debugSet = mState & NS_STATE_CURRENTLY_IN_DEBUG; - bool debugChanged = (!aDebug && debugSet) || (aDebug && !debugSet); - - // if it doesn't then tell each child below us the new debug state - if (debugChanged) - { - if (aDebug) { - AddStateBits(NS_STATE_CURRENTLY_IN_DEBUG); - } else { - RemoveStateBits(NS_STATE_CURRENTLY_IN_DEBUG); - } - - SetDebugOnChildList(aState, mFirstChild, aDebug); - - MarkIntrinsicISizesDirty(); - } - - return NS_OK; -} -#endif - /* virtual */ void nsBoxFrame::MarkIntrinsicISizesDirty() { SizeNeedsRecalc(mPrefSize); SizeNeedsRecalc(mMinSize); SizeNeedsRecalc(mMaxSize); CoordNeedsRecalc(mFlex); CoordNeedsRecalc(mAscent); @@ -1070,22 +969,16 @@ nsBoxFrame::InsertFrames(ChildListID mLayoutManager->ChildrenInserted(this, state, aPrevFrame, newFrames); // Make sure to check box order _after_ notifying the layout // manager; otherwise the slice we give the layout manager will // just be bogus. If the layout manager cares about the order, we // just lose. CheckBoxOrder(); -#ifdef DEBUG_LAYOUT - // if we are in debug make sure our children are in debug as well. - if (mState & NS_STATE_CURRENTLY_IN_DEBUG) - SetDebugOnChildList(state, mFrames.FirstChild(), true); -#endif - PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange, NS_FRAME_HAS_DIRTY_CHILDREN); } void nsBoxFrame::AppendFrames(ChildListID aListID, nsFrameList& aFrameList) @@ -1101,22 +994,16 @@ nsBoxFrame::AppendFrames(ChildListID mLayoutManager->ChildrenAppended(this, state, newFrames); // Make sure to check box order _after_ notifying the layout // manager; otherwise the slice we give the layout manager will // just be bogus. If the layout manager cares about the order, we // just lose. CheckBoxOrder(); -#ifdef DEBUG_LAYOUT - // if we are in debug make sure our children are in debug as well. - if (mState & NS_STATE_CURRENTLY_IN_DEBUG) - SetDebugOnChildList(state, mFrames.FirstChild(), true); -#endif - // XXXbz why is this NS_FRAME_FIRST_REFLOW check here? if (!(GetStateBits() & NS_FRAME_FIRST_REFLOW)) { PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange, NS_FRAME_HAS_DIRTY_CHILDREN); } } /* virtual */ nsContainerFrame* @@ -1169,19 +1056,16 @@ nsBoxFrame::AttributeChanged(int32_t aNa aAttribute == nsGkAtoms::dir || aAttribute == nsGkAtoms::mousethrough || aAttribute == nsGkAtoms::equalsize) { if (aAttribute == nsGkAtoms::align || aAttribute == nsGkAtoms::valign || aAttribute == nsGkAtoms::orient || aAttribute == nsGkAtoms::pack || -#ifdef DEBUG_LAYOUT - aAttribute == nsGkAtoms::debug || -#endif aAttribute == nsGkAtoms::dir) { mValign = nsBoxFrame::vAlign_Top; mHalign = nsBoxFrame::hAlign_Left; bool orient = true; GetInitialOrientation(orient); if (orient) @@ -1201,31 +1085,16 @@ nsBoxFrame::AttributeChanged(int32_t aNa bool equalSize = false; GetInitialEqualSize(equalSize); if (equalSize) AddStateBits(NS_STATE_EQUAL_SIZE); else RemoveStateBits(NS_STATE_EQUAL_SIZE); -#ifdef DEBUG_LAYOUT - bool debug = mState & NS_STATE_SET_TO_DEBUG; - bool debugSet = GetInitialDebug(debug); - if (debugSet) { - AddStateBits(NS_STATE_DEBUG_WAS_SET); - - if (debug) - AddStateBits(NS_STATE_SET_TO_DEBUG); - else - RemoveStateBits(NS_STATE_SET_TO_DEBUG); - } else { - RemoveStateBits(NS_STATE_DEBUG_WAS_SET); - } -#endif - bool autostretch = !!(mState & NS_STATE_AUTO_STRETCH); GetInitialAutoStretch(autostretch); if (autostretch) AddStateBits(NS_STATE_AUTO_STRETCH); else RemoveStateBits(NS_STATE_AUTO_STRETCH); } else if (aAttribute == nsGkAtoms::left || @@ -1269,63 +1138,16 @@ nsBoxFrame::AttributeChanged(int32_t aNa // nsTreeBodyFrame's layout reads this from its parent (this frame). PresShell()->FrameNeedsReflow(this, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY); } return rv; } -#ifdef DEBUG_LAYOUT -void -nsBoxFrame::GetDebugPref() -{ - gDebug = Preferences::GetBool("xul.debug.box"); -} - -class nsDisplayXULDebug : public nsDisplayItem { -public: - nsDisplayXULDebug(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) : - nsDisplayItem(aBuilder, aFrame) { - MOZ_COUNT_CTOR(nsDisplayXULDebug); - } -#ifdef NS_BUILD_REFCNT_LOGGING - virtual ~nsDisplayXULDebug() { - MOZ_COUNT_DTOR(nsDisplayXULDebug); - } -#endif - - virtual void HitTest(nsDisplayListBuilder* aBuilder, nsRect aRect, - HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) { - nsPoint rectCenter(aRect.x + aRect.width / 2, aRect.y + aRect.height / 2); - static_cast<nsBoxFrame*>(mFrame)-> - DisplayDebugInfoFor(this, rectCenter - ToReferenceFrame()); - aOutFrames->AppendElement(this); - } - virtual void Paint(nsDisplayListBuilder* aBuilder - gfxContext* aCtx); - NS_DISPLAY_DECL_NAME("XULDebug", TYPE_XUL_DEBUG) -}; - -void -nsDisplayXULDebug::Paint(nsDisplayListBuilder* aBuilder, - gfxContext* aCtx) -{ - static_cast<nsBoxFrame*>(mFrame)-> - PaintXULDebugOverlay(*aCtx->GetDrawTarget(), ToReferenceFrame()); -} - -static void -PaintXULDebugBackground(nsIFrame* aFrame, DrawTarget* aDrawTarget, - const nsRect& aDirtyRect, nsPoint aPt) -{ - static_cast<nsBoxFrame*>(aFrame)->PaintXULDebugBackground(aDrawTarget, aPt); -} -#endif - void nsBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsDisplayListSet& aLists) { bool forceLayer = false; if (GetContent()->IsXULElement()) { // forcelayer is only supported on XUL elements with box layout @@ -1342,26 +1164,16 @@ nsBoxFrame::BuildDisplayList(nsDisplayLi } } nsDisplayListCollection tempLists(aBuilder); const nsDisplayListSet& destination = forceLayer ? tempLists : aLists; DisplayBorderBackgroundOutline(aBuilder, destination); -#ifdef DEBUG_LAYOUT - if (mState & NS_STATE_CURRENTLY_IN_DEBUG) { - destination.BorderBackground()->AppendToTop( - MakeDisplayItem<nsDisplayGeneric>(aBuilder, this, PaintXULDebugBackground, - "XULDebugBackground")); - destination.Outlines()->AppendToTop( - MakeDisplayItem<nsDisplayXULDebug>(aBuilder, this)); - } -#endif - Maybe<nsDisplayListBuilder::AutoContainerASRTracker> contASRTracker; if (forceLayer) { contASRTracker.emplace(aBuilder); } BuildDisplayListForChildren(aBuilder, destination); // see if we have to draw a selection frame around this container @@ -1402,486 +1214,24 @@ nsBoxFrame::BuildDisplayListForChildren( nsDisplayListSet set(aLists, aLists.BlockBorderBackgrounds()); // The children should be in the right order while (kid) { BuildDisplayListForChild(aBuilder, kid, set); kid = kid->GetNextSibling(); } } -// REVIEW: PaintChildren did a few things none of which are a big deal -// anymore: -// * Paint some debugging rects for this frame. -// This is done by nsDisplayXULDebugBackground, which goes in the -// BorderBackground() layer so it isn't clipped by OVERFLOW_CLIP. -// * Apply OVERFLOW_CLIP to the children. -// This is now in nsFrame::BuildDisplayListForStackingContext/Child. -// * Actually paint the children. -// Moved to BuildDisplayList. -// * Paint per-kid debug information. -// This is done by nsDisplayXULDebug, which is in the Outlines() -// layer so it goes on top. This means it is not clipped by OVERFLOW_CLIP, -// whereas it did used to respect OVERFLOW_CLIP, but too bad. -#ifdef DEBUG_LAYOUT -void -nsBoxFrame::PaintXULDebugBackground(DrawTarget* aDrawTarget, nsPoint aPt) -{ - nsMargin border; - GetXULBorder(border); - - nsMargin debugBorder; - nsMargin debugMargin; - nsMargin debugPadding; - - bool isHorizontal = IsXULHorizontal(); - - GetDebugBorder(debugBorder); - PixelMarginToTwips(debugBorder); - - GetDebugMargin(debugMargin); - PixelMarginToTwips(debugMargin); - - GetDebugPadding(debugPadding); - PixelMarginToTwips(debugPadding); - - nsRect inner(mRect); - inner.MoveTo(aPt); - inner.Deflate(debugMargin); - inner.Deflate(border); - //nsRect borderRect(inner); - - int32_t appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel(); - - ColorPattern color(ToDeviceColor(isHorizontal ? Color(0.f, 0.f, 1.f, 1.f) : - Color(1.f, 0.f, 0.f, 1.f))); - - //left - nsRect r(inner); - r.width = debugBorder.left; - aDrawTarget->FillRect(NSRectToRect(r, appUnitsPerDevPixel), color); - - // top - r = inner; - r.height = debugBorder.top; - aDrawTarget->FillRect(NSRectToRect(r, appUnitsPerDevPixel), color); - - //right - r = inner; - r.x = r.x + r.width - debugBorder.right; - r.width = debugBorder.right; - aDrawTarget->FillRect(NSRectToRect(r, appUnitsPerDevPixel), color); - - //bottom - r = inner; - r.y = r.y + r.height - debugBorder.bottom; - r.height = debugBorder.bottom; - aDrawTarget->FillRect(NSRectToRect(r, appUnitsPerDevPixel), color); - - // If we have dirty children or we are dirty place a green border around us. - if (NS_SUBTREE_DIRTY(this)) { - nsRect dirty(inner); - ColorPattern green(ToDeviceColor(Color(0.f, 1.f, 0.f, 1.f))); - aDrawTarget->StrokeRect(NSRectToRect(dirty, appUnitsPerDevPixel), green); - } -} - -void -nsBoxFrame::PaintXULDebugOverlay(DrawTarget& aDrawTarget, nsPoint aPt) -{ - nsMargin border; - GetXULBorder(border); - - nsMargin debugMargin; - GetDebugMargin(debugMargin); - PixelMarginToTwips(debugMargin); - - nsRect inner(mRect); - inner.MoveTo(aPt); - inner.Deflate(debugMargin); - inner.Deflate(border); - - nscoord onePixel = GetPresContext()->IntScaledPixelsToTwips(1); - - kid = nsBox::GetChildXULBox(this); - while (nullptr != kid) { - bool isHorizontal = IsXULHorizontal(); - - nscoord x, y, borderSize, spacerSize; - - nsRect cr(kid->mRect); - nsMargin margin; - kid->GetXULMargin(margin); - cr.Inflate(margin); - - if (isHorizontal) - { - cr.y = inner.y; - x = cr.x; - y = cr.y + onePixel; - spacerSize = debugBorder.top - onePixel*4; - } else { - cr.x = inner.x; - x = cr.y; - y = cr.x + onePixel; - spacerSize = debugBorder.left - onePixel*4; - } - - nscoord flex = kid->GetXULFlex(); - - if (!kid->IsXULCollapsed()) { - if (isHorizontal) - borderSize = cr.width; - else - borderSize = cr.height; - - DrawSpacer(GetPresContext(), aDrawTarget, isHorizontal, flex, x, y, borderSize, spacerSize); - } - - kid = GetNextXULBox(kid); - } -} -#endif - -#ifdef DEBUG_LAYOUT -void -nsBoxFrame::GetBoxName(nsAutoString& aName) -{ - GetFrameName(aName); -} -#endif - #ifdef DEBUG_FRAME_DUMP nsresult nsBoxFrame::GetFrameName(nsAString& aResult) const { return MakeFrameName(NS_LITERAL_STRING("Box"), aResult); } #endif -#ifdef DEBUG_LAYOUT -nsresult -nsBoxFrame::GetXULDebug(bool& aDebug) -{ - aDebug = (mState & NS_STATE_CURRENTLY_IN_DEBUG); - return NS_OK; -} -#endif - -// REVIEW: nsBoxFrame::GetFrameForPoint is a problem because of 'mousethrough' -// attribute support. Here's how it works: -// * For each child frame F, we determine the target frame T(F) by recursively -// invoking GetFrameForPoint on the child -// * Let F' be the last child frame such that T(F') doesn't have mousethrough. -// If F' exists, return T(F') -// * Otherwise let F'' be the first child frame such that T(F'') is non-null. -// If F'' exists, return T(F'') -// * Otherwise return this frame, if this frame contains the point -// * Otherwise return null -// It's not clear how this should work for more complex z-ordering situations. -// The basic principle seems to be that if a frame F has a descendant -// 'mousethrough' frame that includes the target position, then F -// will not receive events (unless it overrides GetFrameForPoint). -// A 'mousethrough' frame will only receive an event if, after applying that rule, -// all eligible frames are 'mousethrough'; the bottom-most inner-most 'mousethrough' -// frame is then chosen (the first eligible frame reached in a -// traversal of the frame tree --- pre/post is irrelevant since ancestors -// of the mousethrough frames can't be eligible). -// IMHO this is very bogus and adds a great deal of complexity for something -// that is very rarely used. So I'm redefining 'mousethrough' to the following: -// a frame with mousethrough is transparent to mouse events. This is compatible -// with the way 'mousethrough' is used in Seamonkey's navigator.xul and -// Firefox's browser.xul. The only other place it's used is in the 'expander' -// XBL binding, which in our tree is only used by Thunderbird SMIME Advanced -// Preferences, and I can't figure out what that does, so I'll have to test it. -// If it's broken I'll probably just change the binding to use it more sensibly. -// This new behaviour is implemented in nsDisplayList::HitTest. -// REVIEW: This debug-box stuff is annoying. I'm just going to put debug boxes -// in the outline layer and avoid GetDebugBoxAt. - -// REVIEW: GetCursor had debug-only event dumping code. I have replaced it -// with instrumentation in nsDisplayXULDebug. - -#ifdef DEBUG_LAYOUT -void -nsBoxFrame::DrawLine(DrawTarget& aDrawTarget, bool aHorizontal, nscoord x1, nscoord y1, nscoord x2, nscoord y2) -{ - nsPoint p1(x1, y1); - nsPoint p2(x2, y2); - if (!aHorizontal) { - Swap(p1.x, p1.y); - Swap(p2.x, p2.y); - } - ColorPattern white(ToDeviceColor(Color(1.f, 1.f, 1.f, 1.f))); - StrokeLineWithSnapping(p1, p2, PresContext()->AppUnitsPerDevPixel(), - aDrawTarget, color); -} - -void -nsBoxFrame::FillRect(DrawTarget& aDrawTarget, bool aHorizontal, nscoord x, nscoord y, nscoord width, nscoord height) -{ - Rect rect = NSRectToSnappedRect(aHorizontal ? nsRect(x, y, width, height) : - nsRect(y, x, height, width), - PresContext()->AppUnitsPerDevPixel(), - aDrawTarget); - ColorPattern white(ToDeviceColor(Color(1.f, 1.f, 1.f, 1.f))); - aDrawTarget.FillRect(rect, white); -} - -void -nsBoxFrame::DrawSpacer(nsPresContext* aPresContext, DrawTarget& aDrawTarget, - bool aHorizontal, int32_t flex, nscoord x, nscoord y, - nscoord size, nscoord spacerSize) -{ - nscoord onePixel = aPresContext->IntScaledPixelsToTwips(1); - - // if we do draw the coils - int distance = 0; - int center = 0; - int offset = 0; - int coilSize = COIL_SIZE*onePixel; - int halfSpacer = spacerSize/2; - - distance = size; - center = y + halfSpacer; - offset = x; - - int coils = distance/coilSize; - - int halfCoilSize = coilSize/2; - - if (flex == 0) { - DrawLine(aDrawTarget, aHorizontal, x,y + spacerSize/2, x + size, y + spacerSize/2); - } else { - for (int i=0; i < coils; i++) - { - DrawLine(aDrawTarget, aHorizontal, offset, center+halfSpacer, offset+halfCoilSize, center-halfSpacer); - DrawLine(aDrawTarget, aHorizontal, offset+halfCoilSize, center-halfSpacer, offset+coilSize, center+halfSpacer); - - offset += coilSize; - } - } - - FillRect(aDrawTarget, aHorizontal, x + size - spacerSize/2, y, spacerSize/2, spacerSize); - FillRect(aDrawTarget, aHorizontal, x, y, spacerSize/2, spacerSize); -} - -void -nsBoxFrame::GetDebugBorder(nsMargin& aInset) -{ - aInset.SizeTo(2,2,2,2); - - if (IsXULHorizontal()) - aInset.top = 10; - else - aInset.left = 10; -} - -void -nsBoxFrame::GetDebugMargin(nsMargin& aInset) -{ - aInset.SizeTo(2,2,2,2); -} - -void -nsBoxFrame::GetDebugPadding(nsMargin& aPadding) -{ - aPadding.SizeTo(2,2,2,2); -} - -void -nsBoxFrame::PixelMarginToTwips(nsMargin& aMarginPixels) -{ - nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1); - aMarginPixels.left *= onePixel; - aMarginPixels.right *= onePixel; - aMarginPixels.top *= onePixel; - aMarginPixels.bottom *= onePixel; -} - -void -nsBoxFrame::GetValue(nsPresContext* aPresContext, const nsSize& a, const nsSize& b, char* ch) -{ - float p2t = aPresContext->ScaledPixelsToTwips(); - - char width[100]; - char height[100]; - - if (a.width == NS_INTRINSICSIZE) - sprintf(width,"%s","INF"); - else - sprintf(width,"%d", nscoord(a.width/*/p2t*/)); - - if (a.height == NS_INTRINSICSIZE) - sprintf(height,"%s","INF"); - else - sprintf(height,"%d", nscoord(a.height/*/p2t*/)); - - - sprintf(ch, "(%s%s, %s%s)", width, (b.width != NS_INTRINSICSIZE ? "[SET]" : ""), - height, (b.height != NS_INTRINSICSIZE ? "[SET]" : "")); - -} - -void -nsBoxFrame::GetValue(nsPresContext* aPresContext, int32_t a, int32_t b, char* ch) -{ - if (a == NS_INTRINSICSIZE) - sprintf(ch, "%d[SET]", b); - else - sprintf(ch, "%d", a); -} - -nsresult -nsBoxFrame::DisplayDebugInfoFor(nsIFrame* aBox, - nsPoint& aPoint) -{ - nsBoxLayoutState state(GetPresContext()); - - nscoord x = aPoint.x; - nscoord y = aPoint.y; - - // get the area inside our border but not our debug margins. - nsRect insideBorder(aBox->mRect); - insideBorder.MoveTo(0,0): - nsMargin border(0,0,0,0); - aBox->GetXULBorderAndPadding(border); - insideBorder.Deflate(border); - - bool isHorizontal = IsXULHorizontal(); - - if (!insideBorder.Contains(nsPoint(x,y))) - return NS_ERROR_FAILURE; - - //printf("%%%%%% inside box %%%%%%%\n"); - - int count = 0; - nsIFrame* child = nsBox::GetChildXULBox(aBox); - - nsMargin m; - nsMargin m2; - GetDebugBorder(m); - PixelMarginToTwips(m); - - GetDebugMargin(m2); - PixelMarginToTwips(m2); - - m += m2; - - if ((isHorizontal && y < insideBorder.y + m.top) || - (!isHorizontal && x < insideBorder.x + m.left)) { - //printf("**** inside debug border *******\n"); - while (child) - { - const nsRect& r = child->mRect; - - // if we are not in the child. But in the spacer above the child. - if ((isHorizontal && x >= r.x && x < r.x + r.width) || - (!isHorizontal && y >= r.y && y < r.y + r.height)) { - aCursor = NS_STYLE_CURSOR_POINTER; - // found it but we already showed it. - if (mDebugChild == child) - return NS_OK; - - if (aBox->GetContent()) { - printf("---------------\n"); - XULDumpBox(stdout); - printf("\n"); - } - - if (child->GetContent()) { - printf("child #%d: ", count); - child->XULDumpBox(stdout); - printf("\n"); - } - - mDebugChild = child; - - nsSize prefSizeCSS(NS_INTRINSICSIZE, NS_INTRINSICSIZE); - nsSize minSizeCSS (NS_INTRINSICSIZE, NS_INTRINSICSIZE); - nsSize maxSizeCSS (NS_INTRINSICSIZE, NS_INTRINSICSIZE); - nscoord flexCSS = NS_INTRINSICSIZE; - - bool widthSet, heightSet; - nsIFrame::AddXULPrefSize(child, prefSizeCSS, widthSet, heightSet); - nsIFrame::AddXULMinSize (state, child, minSizeCSS, widthSet, heightSet); - nsIFrame::AddXULMaxSize (child, maxSizeCSS, widthSet, heightSet); - nsIFrame::AddXULFlex (child, flexCSS); - - nsSize prefSize = child->GetXULPrefSize(state); - nsSize minSize = child->GetXULMinSize(state); - nsSize maxSize = child->GetXULMaxSize(state); - nscoord flexSize = child->GetXULFlex(); - nscoord ascentSize = child->GetXULBoxAscent(state); - - char min[100]; - char pref[100]; - char max[100]; - char calc[100]; - char flex[100]; - char ascent[100]; - - nsSize actualSize; - GetFrameSizeWithMargin(child, actualSize); - nsSize actualSizeCSS (NS_INTRINSICSIZE, NS_INTRINSICSIZE); - - GetValue(aPresContext, minSize, minSizeCSS, min); - GetValue(aPresContext, prefSize, prefSizeCSS, pref); - GetValue(aPresContext, maxSize, maxSizeCSS, max); - GetValue(aPresContext, actualSize, actualSizeCSS, calc); - GetValue(aPresContext, flexSize, flexCSS, flex); - GetValue(aPresContext, ascentSize, NS_INTRINSICSIZE, ascent); - - - printf("min%s, pref%s, max%s, actual%s, flex=%s, ascent=%s\n\n", - min, - pref, - max, - calc, - flex, - ascent - ); - - return NS_OK; - } - - child = GetNextXULBox(child); - count++; - } - } else { - } - - mDebugChild = nullptr; - - return NS_OK; -} - -void -nsBoxFrame::SetDebugOnChildList(nsBoxLayoutState& aState, nsIFrame* aChild, bool aDebug) -{ - nsIFrame* child = nsBox::GetChildXULBox(this); - while (child) - { - child->SetXULDebug(aState, aDebug); - child = GetNextXULBox(child); - } -} - -nsresult -nsBoxFrame::GetFrameSizeWithMargin(nsIFrame* aBox, nsSize& aSize) -{ - nsRect rect(aBox->GetRect()); - nsMargin margin(0,0,0,0); - aBox->GetXULMargin(margin); - rect.Inflate(margin); - aSize.width = rect.width; - aSize.height = rect.height; - return NS_OK; -} -#endif - // If you make changes to this function, check its counterparts // in nsTextBoxFrame and nsXULLabelFrame void nsBoxFrame::RegUnregAccessKey(bool aDoReg) { MOZ_ASSERT(mContent); // only support accesskeys for the following elements
--- a/layout/xul/nsBoxFrame.h +++ b/layout/xul/nsBoxFrame.h @@ -61,20 +61,16 @@ public: virtual nsresult XULRelayoutChildAtOrdinal(nsIFrame* aChild) override; virtual nsSize GetXULPrefSize(nsBoxLayoutState& aBoxLayoutState) override; virtual nsSize GetXULMinSize(nsBoxLayoutState& aBoxLayoutState) override; virtual nsSize GetXULMaxSize(nsBoxLayoutState& aBoxLayoutState) override; virtual nscoord GetXULFlex() override; virtual nscoord GetXULBoxAscent(nsBoxLayoutState& aBoxLayoutState) override; -#ifdef DEBUG_LAYOUT - virtual nsresult SetXULDebug(nsBoxLayoutState& aBoxLayoutState, bool aDebug) override; - virtual nsresult GetXULDebug(bool& aDebug) override; -#endif virtual Valignment GetXULVAlign() const override { return mValign; } virtual Halignment GetXULHAlign() const override { return mHalign; } NS_IMETHOD DoXULLayout(nsBoxLayoutState& aBoxLayoutState) override; virtual bool ComputesOwnOverflowArea() override { return false; } // ----- child and sibling operations --- @@ -141,22 +137,16 @@ public: // virtual so nsStackFrame, nsButtonBoxFrame, nsSliderFrame and nsMenuFrame // can override it virtual void BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, const nsDisplayListSet& aLists); virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsDisplayListSet& aLists) override; -#ifdef DEBUG_LAYOUT - virtual void SetDebugOnChildList(nsBoxLayoutState& aState, nsIFrame* aChild, bool aDebug); - nsresult DisplayDebugInfoFor(nsIFrame* aBox, - nsPoint& aPoint); -#endif - static nsresult LayoutChildAt(nsBoxLayoutState& aState, nsIFrame* aBox, const nsRect& aRect); /** * Utility method to redirect events on descendants to this frame. * Supports 'allowevents' attribute on descendant elements to allow those * elements and their descendants to receive events. */ void WrapListsInRedirector(nsDisplayListBuilder* aBuilder, @@ -177,24 +167,16 @@ public: private: explicit nsBoxFrame(ComputedStyle* aStyle) : nsBoxFrame(aStyle, kClassID, false, nullptr) {} protected: nsBoxFrame(ComputedStyle* aStyle, ClassID aID, bool aIsRoot = false, nsBoxLayout* aLayoutManager = nullptr); virtual ~nsBoxFrame(); -#ifdef DEBUG_LAYOUT - virtual void GetBoxName(nsAutoString& aName) override; - void PaintXULDebugBackground(gfxContext& aRenderingContext, - nsPoint aPt); - void PaintXULDebugOverlay(DrawTarget& aRenderingContext, - nsPoint aPt); -#endif - virtual bool GetInitialEqualSize(bool& aEqualSize); virtual void GetInitialOrientation(bool& aIsHorizontal); virtual void GetInitialDirection(bool& aIsNormal); virtual bool GetInitialHAlignment(Halignment& aHalign); virtual bool GetInitialVAlignment(Valignment& aValign); virtual bool GetInitialAutoStretch(bool& aStretch); virtual void DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData) override; @@ -217,44 +199,20 @@ protected: protected: void RegUnregAccessKey(bool aDoReg); void CheckBoxOrder(); private: -#ifdef DEBUG_LAYOUT - nsresult SetXULDebug(nsPresContext* aPresContext, bool aDebug); - bool GetInitialDebug(bool& aDebug); - void GetDebugPref(); - - void GetDebugBorder(nsMargin& aInset); - void GetDebugPadding(nsMargin& aInset); - void GetDebugMargin(nsMargin& aInset); - - nsresult GetFrameSizeWithMargin(nsIFrame* aBox, nsSize& aSize); - - void PixelMarginToTwips(nsMargin& aMarginPixels); - - void GetValue(nsPresContext* aPresContext, const nsSize& a, const nsSize& b, char* value); - void GetValue(nsPresContext* aPresContext, int32_t a, int32_t b, char* value); - void DrawSpacer(nsPresContext* aPresContext, DrawTarget& aDrawTarget, bool aHorizontal, int32_t flex, nscoord x, nscoord y, nscoord size, nscoord spacerSize); - void DrawLine(DrawTarget& aDrawTarget, bool aHorizontal, nscoord x1, nscoord y1, nscoord x2, nscoord y2); - void FillRect(DrawTarget& aDrawTarget, bool aHorizontal, nscoord x, nscoord y, nscoord width, nscoord height); -#endif virtual void UpdateMouseThrough(); void CacheAttributes(); // instance variables. Halignment mHalign; Valignment mValign; -#ifdef DEBUG_LAYOUT - static bool gDebug; - static nsIFrame* mDebugChild; -#endif - }; // class nsBoxFrame #endif
--- a/layout/xul/nsLeafBoxFrame.cpp +++ b/layout/xul/nsLeafBoxFrame.cpp @@ -36,25 +36,16 @@ using namespace mozilla; nsIFrame* NS_NewLeafBoxFrame (nsIPresShell* aPresShell, ComputedStyle* aStyle) { return new (aPresShell) nsLeafBoxFrame(aStyle); } NS_IMPL_FRAMEARENA_HELPERS(nsLeafBoxFrame) -#ifdef DEBUG_LAYOUT -void -nsLeafBoxFrame::GetBoxName(nsAutoString& aName) -{ - GetFrameName(aName); -} -#endif - - /** * Initialize us. This is a good time to get the alignment of the box */ void nsLeafBoxFrame::Init(nsIContent* aContent, nsContainerFrame* aParent, nsIFrame* aPrevInFlow) {
--- a/layout/xul/nsLeafBoxFrame.h +++ b/layout/xul/nsLeafBoxFrame.h @@ -71,20 +71,16 @@ public: int32_t aModType) override; virtual bool ComputesOwnOverflowArea() override { return false; } protected: NS_IMETHOD DoXULLayout(nsBoxLayoutState& aState) override; -#ifdef DEBUG_LAYOUT - virtual void GetBoxName(nsAutoString& aName) override; -#endif - virtual nscoord GetIntrinsicISize() override; explicit nsLeafBoxFrame(ComputedStyle* aStyle, ClassID aID = kClassID) : nsLeafFrame(aStyle, aID) {} private:
--- a/layout/xul/nsMenuFrame.cpp +++ b/layout/xul/nsMenuFrame.cpp @@ -764,53 +764,16 @@ nsMenuFrame::DoXULLayout(nsBoxLayoutStat if (popupFrame) { bool sizeToPopup = IsSizedToPopup(mContent, false); popupFrame->LayoutPopup(aState, this, GetAnchor()->GetPrimaryFrame(), sizeToPopup); } return rv; } -#ifdef DEBUG_LAYOUT -nsresult -nsMenuFrame::SetXULDebug(nsBoxLayoutState& aState, bool aDebug) -{ - // see if our state matches the given debug state - bool debugSet = mState & NS_STATE_CURRENTLY_IN_DEBUG; - bool debugChanged = (!aDebug && debugSet) || (aDebug && !debugSet); - - // if it doesn't then tell each child below us the new debug state - if (debugChanged) - { - nsBoxFrame::SetXULDebug(aState, aDebug); - nsMenuPopupFrame* popupFrame = GetPopup(); - if (popupFrame) - SetXULDebug(aState, popupFrame, aDebug); - } - - return NS_OK; -} - -nsresult -nsMenuFrame::SetXULDebug(nsBoxLayoutState& aState, nsIFrame* aList, bool aDebug) -{ - if (!aList) - return NS_OK; - - while (aList) { - if (aList->IsXULBoxFrame()) - aList->SetXULDebug(aState, aDebug); - - aList = aList->GetNextSibling(); - } - - return NS_OK; -} -#endif - // // Enter // // Called when the user hits the <Enter>/<Return> keys or presses the // shortcut key. If this is a leaf item, the item's action will be executed. // In either case, do nothing if the item is disabled. // nsMenuFrame* @@ -1329,21 +1292,16 @@ nsMenuFrame::RemoveFrame(ChildListID void nsMenuFrame::InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, nsFrameList& aFrameList) { if (!HasPopup() && (aListID == kPrincipalList || aListID == kPopupList)) { SetPopupFrame(aFrameList); if (HasPopup()) { -#ifdef DEBUG_LAYOUT - nsBoxLayoutState state(PresContext()); - SetXULDebug(state, aFrameList, mState & NS_STATE_CURRENTLY_IN_DEBUG); -#endif - PresShell()-> FrameNeedsReflow(this, nsIPresShell::eTreeChange, NS_FRAME_HAS_DIRTY_CHILDREN); } } if (aFrameList.IsEmpty()) return; @@ -1357,21 +1315,16 @@ nsMenuFrame::InsertFrames(ChildListID void nsMenuFrame::AppendFrames(ChildListID aListID, nsFrameList& aFrameList) { if (!HasPopup() && (aListID == kPrincipalList || aListID == kPopupList)) { SetPopupFrame(aFrameList); if (HasPopup()) { - -#ifdef DEBUG_LAYOUT - nsBoxLayoutState state(PresContext()); - SetXULDebug(state, aFrameList, mState & NS_STATE_CURRENTLY_IN_DEBUG); -#endif PresShell()-> FrameNeedsReflow(this, nsIPresShell::eTreeChange, NS_FRAME_HAS_DIRTY_CHILDREN); } } if (aFrameList.IsEmpty()) return;
--- a/layout/xul/nsMenuFrame.h +++ b/layout/xul/nsMenuFrame.h @@ -94,20 +94,16 @@ public: NS_IMETHOD DoXULLayout(nsBoxLayoutState& aBoxLayoutState) override; virtual nsSize GetXULMinSize(nsBoxLayoutState& aBoxLayoutState) override; virtual nsSize GetXULPrefSize(nsBoxLayoutState& aBoxLayoutState) override; virtual void Init(nsIContent* aContent, nsContainerFrame* aParent, nsIFrame* aPrevInFlow) override; -#ifdef DEBUG_LAYOUT - virtual nsresult SetXULDebug(nsBoxLayoutState& aState, bool aDebug) override; -#endif - // The following methods are all overridden so that the menupopup // can be stored in a separate list, so that it doesn't impact reflow of the // actual menu item at all. virtual const nsFrameList& GetChildList(ChildListID aList) const override; virtual void GetChildLists(nsTArray<ChildList>* aLists) const override; virtual void DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData) override; // Overridden to prevent events from going to children of the menu. @@ -269,19 +265,16 @@ protected: bool ShouldBlink(); void StartBlinking(mozilla::WidgetGUIEvent* aEvent, bool aFlipChecked); void StopBlinking(); void CreateMenuCommandEvent(mozilla::WidgetGUIEvent* aEvent, bool aFlipChecked); void PassMenuCommandEventToPopupManager(); protected: -#ifdef DEBUG_LAYOUT - nsresult SetXULDebug(nsBoxLayoutState& aState, nsIFrame* aList, bool aDebug); -#endif nsresult Notify(nsITimer* aTimer); bool mIsMenu; // Whether or not we can even have children or not. bool mChecked; // are we checked? bool mIgnoreAccelTextChange; // temporarily set while determining the accelerator key bool mReflowCallbackPosted; nsMenuType mType;
--- a/layout/xul/nsSliderFrame.cpp +++ b/layout/xul/nsSliderFrame.cpp @@ -485,25 +485,16 @@ nsSliderFrame::DoXULLayout(nsBoxLayoutSt if (!thumbBox) { SyncLayout(aState); return NS_OK; } EnsureOrient(); -#ifdef DEBUG_LAYOUT - if (mState & NS_STATE_DEBUG_WAS_SET) { - if (mState & NS_STATE_SET_TO_DEBUG) - SetXULDebug(aState, true); - else - SetXULDebug(aState, false); - } -#endif - // get the content area inside our borders nsRect clientRect; GetXULClientRect(clientRect); // get the scrollbar nsIFrame* scrollbarBox = GetScrollbar(); nsCOMPtr<nsIContent> scrollbar = GetContentOfBox(scrollbarBox);
--- a/layout/xul/nsSprocketLayout.cpp +++ b/layout/xul/nsSprocketLayout.cpp @@ -20,23 +20,16 @@ #include "nsContainerFrame.h" #include "nsBoxFrame.h" #include "StackArena.h" #include "mozilla/Likely.h" #include <algorithm> nsBoxLayout* nsSprocketLayout::gInstance = nullptr; -//#define DEBUG_GROW - -#define DEBUG_SPRING_SIZE 8 -#define DEBUG_BORDER_SIZE 2 -#define COIL_SIZE 8 - - nsresult NS_NewSprocketLayout(nsCOMPtr<nsBoxLayout>& aNewLayout) { if (!nsSprocketLayout::gInstance) { nsSprocketLayout::gInstance = new nsSprocketLayout(); NS_IF_ADDREF(nsSprocketLayout::gInstance); } // we have not instance variables so just return our static one. @@ -485,17 +478,16 @@ nsSprocketLayout::XULLayout(nsIFrame* aB child->XULLayout(aState); // If the child was a block or inline (e.g., HTML) it may have changed its rect *during* layout. // We have to check for this. nsRect newChildRect(child->GetRect()); if (!newChildRect.IsEqualInterior(childRect)) { #ifdef DEBUG_GROW - child->XULDumpBox(stdout); printf(" GREW from (%d,%d) -> (%d,%d)\n", childRect.width, childRect.height, newChildRect.width, newChildRect.height); #endif newChildRect.Inflate(margin); childRect.Inflate(margin); // The child changed size during layout. The ChildResized method handles this // scenario. ChildResized(aBox, @@ -650,19 +642,16 @@ nsSprocketLayout::PopulateBoxSizes(nsIFr // used for the equal size flag nscoord biggestPrefWidth = 0; nscoord biggestMinWidth = 0; nscoord smallestMaxWidth = NS_INTRINSICSIZE; nsFrameState frameState = nsFrameState(0); GetFrameState(aBox, frameState); - //if (frameState & NS_STATE_CURRENTLY_IN_DEBUG) - // printf("In debug\n"); - aMinSize = 0; aMaxSize = NS_INTRINSICSIZE; bool isHorizontal; if (IsXULHorizontal(aBox)) isHorizontal = true; else
--- a/mozglue/misc/Mutex_posix.cpp +++ b/mozglue/misc/Mutex_posix.cpp @@ -1,34 +1,73 @@ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/Assertions.h" +#include <algorithm> #include <errno.h> #include <pthread.h> #include <stdio.h> +#include <unistd.h> #include "mozilla/PlatformMutex.h" #include "MutexPlatformData_posix.h" +#define REPORT_PTHREADS_ERROR(result, msg) \ + { \ + errno = result; \ + perror(msg); \ + MOZ_CRASH(msg); \ + } + #define TRY_CALL_PTHREADS(call, msg) \ { \ int result = (call); \ if (result != 0) { \ - errno = result; \ - perror(msg); \ - MOZ_CRASH(msg); \ + REPORT_PTHREADS_ERROR(result, msg); \ } \ } +#ifdef XP_DARWIN + +// CPU count. Read concurrently from multiple threads. Written once during the +// first mutex initialization; re-initialization is safe hence relaxed ordering +// is OK. +static mozilla::Atomic<uint32_t, mozilla::MemoryOrdering::Relaxed> sCPUCount(0); + +static void +EnsureCPUCount() +{ + if (sCPUCount) { + return; + } + + // _SC_NPROCESSORS_CONF and _SC_NPROCESSORS_ONLN are common, but not + // standard. +#if defined(_SC_NPROCESSORS_CONF) + long n = sysconf(_SC_NPROCESSORS_CONF); + sCPUCount = (n > 0) ? uint32_t(n) : 1; +#elif defined(_SC_NPROCESSORS_ONLN) + long n = sysconf(_SC_NPROCESSORS_ONLN); + sCPUCount = (n > 0) ? uint32_t(n) : 1; +#else + sCPUCount = 1; +#endif +} + +#endif // XP_DARWIN + mozilla::detail::MutexImpl::MutexImpl() +#ifdef XP_DARWIN + : averageSpins(0) +#endif { pthread_mutexattr_t* attrp = nullptr; // Linux with glibc and FreeBSD support adaptive mutexes that spin // for a short number of tries before sleeping. NSPR's locks did // this, too, and it seems like a reasonable thing to do. #if (defined(__linux__) && defined(__GLIBC__)) || defined(__FreeBSD__) #define ADAPTIVE_MUTEX_SUPPORTED @@ -55,29 +94,90 @@ mozilla::detail::MutexImpl::MutexImpl() TRY_CALL_PTHREADS(pthread_mutex_init(&platformData()->ptMutex, attrp), "mozilla::detail::MutexImpl::MutexImpl: pthread_mutex_init failed"); #if defined(ATTR_REQUIRED) TRY_CALL_PTHREADS(pthread_mutexattr_destroy(&attr), "mozilla::detail::MutexImpl::MutexImpl: pthread_mutexattr_destroy failed"); #endif + +#ifdef XP_DARWIN + EnsureCPUCount(); +#endif } mozilla::detail::MutexImpl::~MutexImpl() { TRY_CALL_PTHREADS(pthread_mutex_destroy(&platformData()->ptMutex), "mozilla::detail::MutexImpl::~MutexImpl: pthread_mutex_destroy failed"); } +inline void +mozilla::detail::MutexImpl::mutexLock() +{ + TRY_CALL_PTHREADS(pthread_mutex_lock(&platformData()->ptMutex), + "mozilla::detail::MutexImpl::mutexLock: pthread_mutex_lock failed"); +} + +#ifdef XP_DARWIN +inline bool +mozilla::detail::MutexImpl::mutexTryLock() +{ + int result = pthread_mutex_trylock(&platformData()->ptMutex); + if (result == 0) { + return true; + } + + if (result == EBUSY) { + return false; + } + + REPORT_PTHREADS_ERROR(result, + "mozilla::detail::MutexImpl::mutexTryLock: pthread_mutex_trylock failed"); +} +#endif + void mozilla::detail::MutexImpl::lock() { - TRY_CALL_PTHREADS(pthread_mutex_lock(&platformData()->ptMutex), - "mozilla::detail::MutexImpl::lock: pthread_mutex_lock failed"); +#ifndef XP_DARWIN + mutexLock(); +#else + // Mutex performance on OSX can be very poor if there's a lot of contention as + // this causes excessive context switching. On Linux/FreeBSD we use the + // adaptive mutex type (PTHREAD_MUTEX_ADAPTIVE_NP) to address this, but this + // isn't available on OSX. The code below is a reimplementation of this + // feature. + + MOZ_ASSERT(sCPUCount); + if (sCPUCount == 1) { + mutexLock(); + return; + } + + if (!mutexTryLock()) { + const int32_t SpinLimit = 100; + + int32_t count = 0; + int32_t maxSpins = std::min(SpinLimit, 2 * averageSpins + 10); + do { + if (count >= maxSpins) { + mutexLock(); + break; + } + asm("pause"); // Hint to the processor that we're spinning. + count++; + } while (!mutexTryLock()); + + // Update moving average. + averageSpins += (count - averageSpins) / 8; + MOZ_ASSERT(averageSpins >= 0 && averageSpins <= SpinLimit); + } +#endif // XP_DARWIN } void mozilla::detail::MutexImpl::unlock() { TRY_CALL_PTHREADS(pthread_mutex_unlock(&platformData()->ptMutex), "mozilla::detail::MutexImpl::unlock: pthread_mutex_unlock failed"); }
--- a/mozglue/misc/PlatformMutex.h +++ b/mozglue/misc/PlatformMutex.h @@ -2,16 +2,17 @@ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_PlatformMutex_h #define mozilla_PlatformMutex_h +#include "mozilla/Atomics.h" #include "mozilla/Attributes.h" #include "mozilla/Move.h" #if !defined(XP_WIN) # include <pthread.h> #endif namespace mozilla { @@ -37,23 +38,34 @@ protected: MFBT_API void unlock(); private: MutexImpl(const MutexImpl&) = delete; void operator=(const MutexImpl&) = delete; MutexImpl(MutexImpl&&) = delete; void operator=(MutexImpl&&) = delete; + void mutexLock(); +#ifdef XP_DARWIN + bool mutexTryLock(); +#endif + PlatformData* platformData(); #if !defined(XP_WIN) void* platformData_[sizeof(pthread_mutex_t) / sizeof(void*)]; static_assert(sizeof(pthread_mutex_t) / sizeof(void*) != 0 && sizeof(pthread_mutex_t) % sizeof(void*) == 0, "pthread_mutex_t must have pointer alignment"); +#ifdef XP_DARWIN + // Moving average of the number of spins it takes to acquire the mutex if we + // have to wait. May be accessed by multiple threads concurrently. Getting the + // latest value is not essential hence relaxed memory ordering is sufficient. + mozilla::Atomic<int32_t, mozilla::MemoryOrdering::Relaxed> averageSpins; +#endif #else void* platformData_[6]; #endif friend class mozilla::detail::ConditionVariableImpl; }; } // namespace detail
new file mode 100644 --- /dev/null +++ b/taskcluster/ci/beetmover-release-source-checksums/kind.yml @@ -0,0 +1,17 @@ +# 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/. + +loader: taskgraph.loader.single_dep:loader + +transforms: + - taskgraph.transforms.name_sanity:transforms + - taskgraph.transforms.beetmover_source_checksums:transforms + - taskgraph.transforms.release_notifications:transforms + - taskgraph.transforms.task:transforms + +kind-dependencies: + - release-source-checksums-signing + +job-template: + shipping-phase: promote
--- a/taskcluster/ci/config.yml +++ b/taskcluster/ci/config.yml @@ -33,18 +33,20 @@ treeherder: 'X': 'Xpcshell tests' 'X-e10s': 'Xpcshell tests with e10s' 'L10n': 'Localised Repacks' 'L10n-Rpk': 'Localized Repackaged Repacks' 'BM-L10n': 'Beetmover for locales' 'BMR-L10n': 'Beetmover repackages for locales' 'c-Up': 'Balrog submission of complete updates' 'cs': 'Checksum signing' + 'css': 'Checksum signing for source' 'rs': 'Repackage signing' - 'BMcs': 'Beetmover checksums,' + 'BMcs': 'Beetmover checksums' + 'BMcss': 'Beetmover checksums for source' 'Aries': 'Aries Device Image' 'Deb7': 'Packages for Debian 7' 'Deb9': 'Packages for Debian 9' 'Nexus 5-L': 'Nexus 5-L Device Image' 'I': 'Docker Image Builds' 'TL': 'Toolchain builds for Linux 64-bits' 'TM': 'Toolchain builds for OSX' 'TMW': 'Toolchain builds for Windows MinGW'
--- a/taskcluster/ci/post-beetmover-checksums-dummy/kind.yml +++ b/taskcluster/ci/post-beetmover-checksums-dummy/kind.yml @@ -6,16 +6,17 @@ loader: taskgraph.loader.transform:loade transforms: - taskgraph.transforms.reverse_chunk_deps:transforms - taskgraph.transforms.release_notifications:transforms - taskgraph.transforms.task:transforms kind-dependencies: - beetmover-checksums + - beetmover-release-source-checksums jobs: firefox-promote: name: post-beetmover-checksums-dummy description: Dummy task to deal with max_dependencies run-on-projects: [] shipping-phase: promote shipping-product: firefox
--- a/taskcluster/ci/release-generate-checksums/kind.yml +++ b/taskcluster/ci/release-generate-checksums/kind.yml @@ -50,55 +50,55 @@ job-defaults: symbol: Rel(GenChcks) kind: test tier: 1 jobs: firefox: shipping-product: firefox attributes: - build_platform: linux64 + build_platform: firefox-release build_type: opt run: extra-config: by-project: mozilla-(release|beta): stage_product: "firefox" bucket_name: "net-mozaws-prod-delivery-firefox" default: stage_product: "firefox" bucket_name: "net-mozaws-stage-delivery-firefox" treeherder: - platform: linux64/opt + platform: firefox-release/opt fennec: shipping-product: fennec attributes: - build_platform: android-nightly + build_platform: fennec-release build_type: opt run: extra-config: by-project: mozilla-(release|beta): stage_product: "mobile" bucket_name: "net-mozaws-prod-delivery-archive" default: stage_product: "mobile" bucket_name: "net-mozaws-stage-delivery-archive" treeherder: - platform: Android/opt + platform: fennec-release/opt devedition: shipping-product: devedition attributes: - build_platform: linux64-devedition + build_platform: devedition-release build_type: opt run: extra-config: by-project: mozilla-beta: stage_product: "devedition" bucket_name: "net-mozaws-prod-delivery-archive" default: stage_product: "devedition" bucket_name: "net-mozaws-stage-delivery-archive" treeherder: - platform: linux64-devedition/opt + platform: devedition-release/opt
new file mode 100644 --- /dev/null +++ b/taskcluster/ci/release-source-checksums-signing/kind.yml @@ -0,0 +1,17 @@ +# 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/. + +loader: taskgraph.loader.single_dep:loader + +transforms: + - taskgraph.transforms.name_sanity:transforms + - taskgraph.transforms.source_checksums_signing:transforms + - taskgraph.transforms.release_notifications:transforms + - taskgraph.transforms.task:transforms + +kind-dependencies: + - beetmover-source + +job-template: + shipping-phase: promote
--- a/taskcluster/ci/release-source-signing/kind.yml +++ b/taskcluster/ci/release-source-signing/kind.yml @@ -1,13 +1,13 @@ # 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/. -loader: taskgraph.loader.build_signing:loader +loader: taskgraph.loader.single_dep:loader transforms: - taskgraph.transforms.name_sanity:transforms - taskgraph.transforms.build_signing:transforms - taskgraph.transforms.signing:transforms - taskgraph.transforms.release_notifications:transforms - taskgraph.transforms.task:transforms
--- a/taskcluster/ci/release-source/kind.yml +++ b/taskcluster/ci/release-source/kind.yml @@ -1,46 +1,62 @@ # 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/. loader: taskgraph.loader.transform:loader kind-dependencies: - - toolchain + - toolchain transforms: - - taskgraph.transforms.build:transforms - - taskgraph.transforms.build_attrs:transforms - - taskgraph.transforms.build_lints:transforms - - taskgraph.transforms.use_toolchains:transforms - - taskgraph.transforms.release_notifications:transforms - - taskgraph.transforms.job:transforms - - taskgraph.transforms.task:transforms + - taskgraph.transforms.build:transforms + - taskgraph.transforms.build_attrs:transforms + - taskgraph.transforms.build_lints:transforms + - taskgraph.transforms.use_toolchains:transforms + - taskgraph.transforms.release_notifications:transforms + - taskgraph.transforms.job:transforms + - taskgraph.transforms.task:transforms -jobs-from: - - source.yml job-defaults: - shipping-phase: promote - treeherder: - symbol: Src - worker-type: aws-provisioner-v1/gecko-{level}-b-linux - worker: - max-run-time: 3600 - env: - TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/linux64/releng.manifest" - PKG_SRCPACK_BASENAME: source - run: - using: mozharness - actions: [package-source] - script: "mozharness/scripts/fx_desktop_build.py" - config: - - builds/releng_sub_linux_configs/64_source.py - options: [] - tooltool-downloads: public - need-xvfb: false - run-on-projects: [] - toolchains: - - linux64-clang - - linux64-gcc - - linux64-rust - - linux64-sccache + shipping-phase: promote + treeherder: + symbol: Src + worker-type: aws-provisioner-v1/gecko-{level}-b-linux + worker: + max-run-time: 3600 + env: + TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/linux64/releng.manifest" + PKG_SRCPACK_BASENAME: source + run: + using: mozharness + actions: [package-source] + script: "mozharness/scripts/fx_desktop_build.py" + config: + - builds/releng_sub_linux_configs/64_source.py + options: [] + tooltool-downloads: public + need-xvfb: false + run-on-projects: [] + # The build_attrs transform defaults to setting a `skip-unlles-schedules' + # optimization based on the task label. The tasks here don't have corresponding + # schedules defined in mozbuild. + optimization: {} + +jobs: + firefox-source/opt: + description: "Firefox source builder" + treeherder: + platform: firefox-release/opt + shipping-product: firefox + + fennec-source/opt: + description: "Fennec source builder" + treeherder: + platform: fennec-release/opt + shipping-product: fennec + + devedition-source/opt: + description: "Devedition source builder" + treeherder: + platform: devedition-release/opt + shipping-product: devedition
deleted file mode 100644 --- a/taskcluster/ci/release-source/source.yml +++ /dev/null @@ -1,17 +0,0 @@ -linux64-source/opt: - description: "Firefox source builder" - treeherder: - platform: linux64/opt - shipping-product: firefox - -linux64-fennec-source/opt: - description: "Fennec source builder" - treeherder: - platform: android-api-16/opt - shipping-product: fennec - -linux64-devedition-source/opt: - description: "Devedition source builder" - treeherder: - platform: linux64-devedition-source/opt - shipping-product: devedition
--- a/taskcluster/docs/kinds.rst +++ b/taskcluster/docs/kinds.rst @@ -200,22 +200,34 @@ beetmover-source Beetmover-source publishes release source. This is part of release promotion. checksums-signing ----------------- Checksums-signing take as input the checksums file generated by beetmover tasks and sign it via the signing scriptworkers. Returns the same file signed and additional detached signature. +release-source-checksums-signing +------------------------------- +release-source-checksums-signing take as input the checksums file generated by +source-related beetmover task and sign it via the signing scriptworkers. +Returns the same file signed and additional detached signature. + beetmover-checksums ------------------- Beetmover, takes specific artifact checksums and pushes it to a location outside of Taskcluster's task artifacts (archive.mozilla.org as one place) and in the process determines the final location and "pretty" names it (version product name) +beetmover-release-source-checksums +--------------------------------- +Beetmover, takes source specific artifact checksums and pushes it to a location outside +of Taskcluster's task artifacts (archive.mozilla.org as one place) and in the +process determines the final location and "pretty" names it (version product name) + google-play-strings ------------------- Download strings to display on Google Play from https://l10n.mozilla-community.org/stores_l10n/. Artifact is then used by push-apk. push-apk -------- PushApk publishes Android packages onto Google Play Store. Jobs of this kind take
--- a/taskcluster/taskgraph/transforms/beetmover.py +++ b/taskcluster/taskgraph/transforms/beetmover.py @@ -139,22 +139,16 @@ UPSTREAM_ARTIFACT_UNSIGNED_PATHS = { 'linux64-asan-reporter-nightly': # ASan reporter builds don't generate the regular crashreporter symbol # packages, so we shouldn't try to beetmove them filter(lambda a: a != 'target.crashreporter-symbols.zip', _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_EN_US + [ "host/bin/mar", "host/bin/mbsdiff", ]), - 'linux64-source': [ - ], - 'linux64-devedition-source': [ - ], - 'linux64-fennec-source': [ - ], 'android-x86-nightly': _MOBILE_UPSTREAM_ARTIFACTS_UNSIGNED_EN_US, 'android-aarch64-nightly': _MOBILE_UPSTREAM_ARTIFACTS_UNSIGNED_EN_US, 'android-api-16-nightly': _MOBILE_UPSTREAM_ARTIFACTS_UNSIGNED_EN_US, 'macosx64-nightly': _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_EN_US + [ "host/bin/mar", "host/bin/mbsdiff", ], 'macosx64-devedition-nightly': _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_EN_US + [ @@ -212,28 +206,16 @@ UPSTREAM_ARTIFACT_SIGNED_PATHS = { 'linux-devedition-nightly': _DESKTOP_UPSTREAM_ARTIFACTS_SIGNED_EN_US + [ "target.tar.bz2", "target.tar.bz2.asc", ], 'linux64-asan-reporter-nightly': _DESKTOP_UPSTREAM_ARTIFACTS_SIGNED_EN_US + [ "target.tar.bz2", "target.tar.bz2.asc", ], - 'linux64-source': [ - "source.tar.xz", - "source.tar.xz.asc", - ], - 'linux64-devedition-source': [ - "source.tar.xz", - "source.tar.xz.asc", - ], - 'linux64-fennec-source': [ - "source.tar.xz", - "source.tar.xz.asc", - ], 'android-x86-nightly': ["en-US/target.apk"], 'android-aarch64-nightly': ["en-US/target.apk"], 'android-api-16-nightly': ["en-US/target.apk"], 'macosx64-nightly': _DESKTOP_UPSTREAM_ARTIFACTS_SIGNED_EN_US + [ "target.dmg", "target.dmg.asc", ], 'macosx64-devedition-nightly': _DESKTOP_UPSTREAM_ARTIFACTS_SIGNED_EN_US + [ @@ -289,16 +271,24 @@ UPSTREAM_ARTIFACT_SIGNED_PATHS = { 'win64-nightly-l10n': _DESKTOP_UPSTREAM_ARTIFACTS_SIGNED_L10N + [ "target.zip", ], 'win64-devedition-nightly-l10n': _DESKTOP_UPSTREAM_ARTIFACTS_SIGNED_L10N + [ "target.zip", ], } +# Until bug 1331141 is fixed, if you are adding any new artifacts here that +# need to be transfered to S3, please be aware you also need to follow-up +# with a beetmover patch in https://github.com/mozilla-releng/beetmoverscript/. +# See example in bug 1348286 +UPSTREAM_SOURCE_ARTIFACTS = [ + "source.tar.xz", + "source.tar.xz.asc", +] # Voluptuous uses marker objects as dictionary *keys*, but they are not # comparable, so we cast all of the keys back to regular strings task_description_schema = {str(k): v for k, v in task_description_schema.schema.iteritems()} transforms = TransformSequence() # shortcut for a string where task references are allowed @@ -401,16 +391,27 @@ def generate_upstream_artifacts(job, sig build_mapping = UPSTREAM_ARTIFACT_UNSIGNED_PATHS signing_mapping = UPSTREAM_ARTIFACT_SIGNED_PATHS artifact_prefix = get_artifact_prefix(job) if locale: artifact_prefix = '{}/{}'.format(artifact_prefix, locale) platform = "{}-l10n".format(platform) + if platform.endswith("-source"): + return [ + { + "taskId": {"task-reference": signing_task_ref}, + "taskType": "signing", + "paths": ["{}/{}".format(artifact_prefix, p) + for p in UPSTREAM_SOURCE_ARTIFACTS], + "locale": locale or "en-US", + } + ] + upstream_artifacts = [] # Some platforms (like android-api-16-nightly-l10n) may not depend on any unsigned artifact if build_mapping[platform]: upstream_artifacts.append({ "taskId": {"task-reference": build_task_ref}, "taskType": "build", "paths": ["{}/{}".format(artifact_prefix, p) @@ -445,21 +446,18 @@ def generate_upstream_artifacts(job, sig return upstream_artifacts def craft_release_properties(config, job): params = config.params build_platform = job['attributes']['build_platform'] build_platform = build_platform.replace('-nightly', '') - if 'fennec-source' in build_platform: - # XXX This case is hardcoded to match the current implementation in beetmover - build_platform = 'android-api-16' - else: - build_platform = build_platform.replace('-source', '') + if build_platform.endswith("-source"): + build_platform = build_platform.replace('-source', '-release') # XXX This should be explicitly set via build attributes or something if 'android' in job['label'] or 'fennec' in job['label']: app_name = 'Fennec' elif config.graph_config['trust-domain'] == 'comm': app_name = 'Thunderbird' else: # XXX Even DevEdition is called Firefox
new file mode 100644 --- /dev/null +++ b/taskcluster/taskgraph/transforms/beetmover_source_checksums.py @@ -0,0 +1,166 @@ +# 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/. +""" +Transform beetmover-release-source-checksums task into an actual task description. +""" + +from __future__ import absolute_import, print_function, unicode_literals + +from taskgraph.transforms.base import TransformSequence +from taskgraph.transforms.beetmover import craft_release_properties +from taskgraph.util.attributes import copy_attributes_from_dependent_job +from taskgraph.util.schema import validate_schema, Schema +from taskgraph.util.scriptworker import (get_beetmover_bucket_scope, + get_beetmover_action_scope, + get_worker_type_for_scope) +from taskgraph.transforms.task import task_description_schema +from voluptuous import Any, Required, Optional + +# Voluptuous uses marker objects as dictionary *keys*, but they are not +# comparable, so we cast all of the keys back to regular strings +task_description_schema = {str(k): v for k, v in task_description_schema.schema.iteritems()} + +transforms = TransformSequence() + +taskref_or_string = Any( + basestring, + {Required('task-reference'): basestring}) + +beetmover_checksums_description_schema = Schema({ + Required('dependent-task'): object, + Required('depname', default='build'): basestring, + Optional('label'): basestring, + Optional('treeherder'): task_description_schema['treeherder'], + Optional('locale'): basestring, + Optional('shipping-phase'): task_description_schema['shipping-phase'], + Optional('shipping-product'): task_description_schema['shipping-product'], +}) + + +@transforms.add +def validate(config, jobs): + for job in jobs: + label = job.get('dependent-task', object).__dict__.get('label', '?no-label?') + validate_schema( + beetmover_checksums_description_schema, job, + "In checksums-signing ({!r} kind) task for {!r}:".format(config.kind, label)) + yield job + + +@transforms.add +def make_beetmover_checksums_description(config, jobs): + for job in jobs: + dep_job = job['dependent-task'] + attributes = dep_job.attributes + + treeherder = job.get('treeherder', {}) + treeherder.setdefault('symbol', 'BMcss(N)') + dep_th_platform = dep_job.task.get('extra', {}).get( + 'treeherder', {}).get('machine', {}).get('platform', '') + treeherder.setdefault('platform', + "{}/opt".format(dep_th_platform)) + treeherder.setdefault('tier', 1) + treeherder.setdefault('kind', 'build') + + label = job['label'] + build_platform = attributes.get('build_platform') + + description = "Beetmover submission of checksums for source file" + + extra = {} + if build_platform.startswith("android"): + extra['product'] = 'fennec' + elif 'devedition' in build_platform: + extra['product'] = 'devedition' + else: + extra['product'] = 'firefox' + + dependent_kind = str(dep_job.kind) + dependencies = {dependent_kind: dep_job.label} + for k, v in dep_job.dependencies.items(): + if k.startswith('beetmover'): + dependencies[k] = v + + attributes = copy_attributes_from_dependent_job(dep_job) + + bucket_scope = get_beetmover_bucket_scope(config) + action_scope = get_beetmover_action_scope(config) + + task = { + 'label': label, + 'description': description, + 'worker-type': get_worker_type_for_scope(config, bucket_scope), + 'scopes': [bucket_scope, action_scope], + 'dependencies': dependencies, + 'attributes': attributes, + 'run-on-projects': dep_job.attributes.get('run_on_projects'), + 'treeherder': treeherder, + 'extra': extra, + } + + if 'shipping-phase' in job: + task['shipping-phase'] = job['shipping-phase'] + + if 'shipping-product' in job: + task['shipping-product'] = job['shipping-product'] + + yield task + + +def generate_upstream_artifacts(refs, platform, locale=None): + # Until bug 1331141 is fixed, if you are adding any new artifacts here that + # need to be transfered to S3, please be aware you also need to follow-up + # with a beetmover patch in https://github.com/mozilla-releng/beetmoverscript/. + # See example in bug 1348286 + common_paths = [ + "public/target-source.checksums", + "public/target-source.checksums.asc", + ] + + upstream_artifacts = [{ + "taskId": {"task-reference": refs["signing"]}, + "taskType": "signing", + "paths": common_paths, + "locale": locale or "en-US", + }] + + return upstream_artifacts + + +@transforms.add +def make_beetmover_checksums_worker(config, jobs): + for job in jobs: + valid_beetmover_job = (len(job["dependencies"]) == 2) + if not valid_beetmover_job: + raise NotImplementedError("Beetmover checksums must have two dependencies.") + + locale = job["attributes"].get("locale") + platform = job["attributes"]["build_platform"] + + refs = { + "beetmover": None, + "signing": None, + } + for dependency in job["dependencies"].keys(): + if dependency.startswith("beetmover"): + refs['beetmover'] = "<{}>".format(dependency) + else: + refs['signing'] = "<{}>".format(dependency) + if None in refs.values(): + raise NotImplementedError( + "Beetmover checksums must have a beetmover and signing dependency!") + + worker = { + 'implementation': 'beetmover', + 'release-properties': craft_release_properties(config, job), + 'upstream-artifacts': generate_upstream_artifacts( + refs, platform, locale + ), + } + + if locale: + worker["locale"] = locale + job["worker"] = worker + + yield job
new file mode 100644 --- /dev/null +++ b/taskcluster/taskgraph/transforms/source_checksums_signing.py @@ -0,0 +1,99 @@ +# 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/. +""" +Transform the checksums signing task into an actual task description. +""" + +from __future__ import absolute_import, print_function, unicode_literals + +from taskgraph.transforms.base import TransformSequence +from taskgraph.util.attributes import copy_attributes_from_dependent_job +from taskgraph.util.schema import validate_schema, Schema +from taskgraph.util.scriptworker import ( + get_signing_cert_scope, + get_worker_type_for_scope, +) +from taskgraph.transforms.task import task_description_schema +from voluptuous import Any, Required, Optional + +# Voluptuous uses marker objects as dictionary *keys*, but they are not +# comparable, so we cast all of the keys back to regular strings +task_description_schema = {str(k): v for k, v in task_description_schema.schema.iteritems()} + +transforms = TransformSequence() + +taskref_or_string = Any( + basestring, + {Required('task-reference'): basestring}) + +checksums_signing_description_schema = Schema({ + Required('dependent-task'): object, + Required('depname', default='beetmover'): basestring, + Optional('label'): basestring, + Optional('treeherder'): task_description_schema['treeherder'], + Optional('shipping-product'): task_description_schema['shipping-product'], + Optional('shipping-phase'): task_description_schema['shipping-phase'], +}) + + +@transforms.add +def validate(config, jobs): + for job in jobs: + label = job.get('dependent-task', object).__dict__.get('label', '?no-label?') + validate_schema( + checksums_signing_description_schema, job, + "In checksums-signing ({!r} kind) task for {!r}:".format(config.kind, label)) + yield job + + +@transforms.add +def make_checksums_signing_description(config, jobs): + for job in jobs: + dep_job = job['dependent-task'] + attributes = dep_job.attributes + + treeherder = job.get('treeherder', {}) + treeherder.setdefault('symbol', 'css(N)') + dep_th_platform = dep_job.task.get('extra', {}).get( + 'treeherder', {}).get('machine', {}).get('platform', '') + treeherder.setdefault('platform', + "{}/opt".format(dep_th_platform)) + treeherder.setdefault('tier', 1) + treeherder.setdefault('kind', 'build') + + label = job['label'] + description = "Signing of release-source checksums file" + dependencies = {"beetmover": dep_job.label} + + attributes = copy_attributes_from_dependent_job(dep_job) + + upstream_artifacts = [{ + "taskId": {"task-reference": "<beetmover>"}, + "taskType": "beetmover", + "paths": [ + "public/target-source.checksums", + ], + "formats": ["gpg"] + }] + + signing_cert_scope = get_signing_cert_scope(config) + + task = { + 'label': label, + 'description': description, + 'worker-type': get_worker_type_for_scope(config, signing_cert_scope), + 'worker': {'implementation': 'scriptworker-signing', + 'upstream-artifacts': upstream_artifacts, + 'max-run-time': 3600}, + 'scopes': [ + signing_cert_scope, + "project:releng:signing:format:gpg" + ], + 'dependencies': dependencies, + 'attributes': attributes, + 'run-on-projects': dep_job.attributes.get('run_on_projects'), + 'treeherder': treeherder, + } + + yield task
--- a/taskcluster/taskgraph/util/scriptworker.py +++ b/taskcluster/taskgraph/util/scriptworker.py @@ -440,17 +440,17 @@ def get_release_config(config): release_config['next_version'] = str(config.params['next_version']) release_config['build_number'] = config.params['build_number'] return release_config def get_signing_cert_scope_per_platform(build_platform, is_nightly, config): if 'devedition' in build_platform: return get_devedition_signing_cert_scope(config) - elif is_nightly or build_platform in ('linux64-source', 'linux64-fennec-source'): + elif is_nightly or build_platform in ('firefox-source', 'fennec-source'): return get_signing_cert_scope(config) else: return add_scope_prefix(config, 'signing:cert:dep-signing') def get_worker_type_for_scope(config, scope): """Get the scriptworker type that will accept the given scope.
--- a/testing/talos/talos/tests/devtools/addon/content/tests/head.js +++ b/testing/talos/talos/tests/devtools/addon/content/tests/head.js @@ -44,17 +44,17 @@ exports.testSetup = function(url) { return damp.testSetup(url); }; exports.testTeardown = function() { return damp.testTeardown(); }; exports.logTestResult = function(name, value) { - damp._results.push(name, value); + damp._results.push({ name, value }); }; function getBrowserWindow() { return Services.wm.getMostRecentWindow("navigator:browser"); } exports.getBrowserWindow = getBrowserWindow; function getActiveTab() {
new file mode 100644 --- /dev/null +++ b/testing/web-platform/meta/css/CSS2/backgrounds/background-root-010.xht.ini @@ -0,0 +1,3 @@ +[background-root-010.xht] + disabled: + if webrender: bug 1453935
--- a/testing/web-platform/meta/css/CSS2/backgrounds/background-root-016.xht.ini +++ b/testing/web-platform/meta/css/CSS2/backgrounds/background-root-016.xht.ini @@ -1,4 +1,3 @@ [background-root-016.xht] - expected: - if debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL - if not debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL + disabled: + if webrender: bug 1453935
--- a/toolkit/content/aboutSupport.js +++ b/toolkit/content/aboutSupport.js @@ -445,16 +445,17 @@ var snapshotFormatters = { addRowFromKey("features", "webgl2WSIInfo"); addRowFromKey("features", "webgl2Renderer"); addRowFromKey("features", "webgl2Version"); addRowFromKey("features", "webgl2DriverExtensions"); addRowFromKey("features", "webgl2Extensions"); addRowFromKey("features", "supportsHardwareH264", "hardwareH264"); addRowFromKey("features", "direct2DEnabled", "#Direct2D"); addRowFromKey("features", "usesTiling"); + addRowFromKey("features", "contentUsesTiling"); addRowFromKey("features", "offMainThreadPaintEnabled"); addRowFromKey("features", "offMainThreadPaintWorkerCount"); if ("directWriteEnabled" in data) { let message = data.directWriteEnabled; if ("directWriteVersion" in data) message += " (" + data.directWriteVersion + ")"; addRow("features", "#DirectWrite", message);
--- a/toolkit/content/widgets/browser.xml +++ b/toolkit/content/widgets/browser.xml @@ -1243,17 +1243,17 @@ // autoscrolling on. So instead we do the same math as Gecko. const scaleFactor = 60 / Math.round(60 / screen.defaultCSSScaleFactor); let minX = left.value / scaleFactor + 0.5 * POPUP_SIZE; let maxX = (left.value + width.value) / scaleFactor - 0.5 * POPUP_SIZE; let minY = top.value / scaleFactor + 0.5 * POPUP_SIZE; let maxY = (top.value + height.value) / scaleFactor - 0.5 * POPUP_SIZE; let popupX = Math.max(minX, Math.min(maxX, screenX)); let popupY = Math.max(minY, Math.min(maxY, screenY)); - this._autoScrollPopup.openPopup(null, "after_start", popupX, popupY); + this._autoScrollPopup.openPopupAtScreen(popupX, popupY); this._ignoreMouseEvents = true; this._scrolling = true; this._startX = screenX; this._startY = screenY; window.addEventListener("mousemove", this, true); window.addEventListener("mousedown", this, true); window.addEventListener("mouseup", this, true);
--- a/toolkit/locales/en-US/chrome/global/aboutSupport.properties +++ b/toolkit/locales/en-US/chrome/global/aboutSupport.properties @@ -96,16 +96,17 @@ unknownFailure = Blocklisted; failure co d3d11layersCrashGuard = D3D11 Compositor d3d11videoCrashGuard = D3D11 Video Decoder d3d9videoCrashGuard = D3D9 Video Decoder glcontextCrashGuard = OpenGL resetOnNextRestart = Reset on Next Restart gpuProcessKillButton = Terminate GPU Process gpuDeviceResetButton = Trigger Device Reset usesTiling = Uses Tiling +contentUsesTiling = Uses Tiling (Content) offMainThreadPaintEnabled = Off Main Thread Painting Enabled offMainThreadPaintWorkerCount = Off Main Thread Painting Worker Count audioBackend = Audio Backend maxAudioChannels = Max Channels channelLayout = Preferred Channel Layout sampleRate = Preferred Sample Rate
--- a/toolkit/modules/Troubleshoot.jsm +++ b/toolkit/modules/Troubleshoot.jsm @@ -419,16 +419,17 @@ var dataProviders = { adapterDriverDate2: "driverDate2", isGPU2Active: null, D2DEnabled: "direct2DEnabled", DWriteEnabled: "directWriteEnabled", DWriteVersion: "directWriteVersion", cleartypeParameters: "clearTypeParameters", UsesTiling: "usesTiling", + ContentUsesTiling: "contentUsesTiling", OffMainThreadPaintEnabled: "offMainThreadPaintEnabled", OffMainThreadPaintWorkerCount: "offMainThreadPaintWorkerCount", }; for (let prop in gfxInfoProps) { try { data[gfxInfoProps[prop] || prop] = gfxInfo[prop]; } catch (e) {}
--- a/toolkit/modules/tests/browser/browser_Troubleshoot.js +++ b/toolkit/modules/tests/browser/browser_Troubleshoot.js @@ -343,16 +343,19 @@ const SNAPSHOT_SCHEMA = { type: "boolean", }, directWriteVersion: { type: "string", }, usesTiling: { type: "boolean", }, + contentUsesTiling: { + type: "boolean", + }, offMainThreadPaintEnabled: { type: "boolean", }, offMainThreadPaintWorkerCount: { type: "number", }, clearTypeParameters: { type: "string",
--- a/widget/GfxInfoBase.cpp +++ b/widget/GfxInfoBase.cpp @@ -1476,16 +1476,23 @@ GfxInfoBase::GetWebRenderEnabled(bool* a NS_IMETHODIMP GfxInfoBase::GetUsesTiling(bool* aUsesTiling) { *aUsesTiling = gfxPlatform::GetPlatform()->UsesTiling(); return NS_OK; } NS_IMETHODIMP +GfxInfoBase::GetContentUsesTiling(bool* aUsesTiling) +{ + *aUsesTiling = gfxPlatform::GetPlatform()->ContentUsesTiling(); + return NS_OK; +} + +NS_IMETHODIMP GfxInfoBase::GetOffMainThreadPaintEnabled(bool* aOffMainThreadPaintEnabled) { *aOffMainThreadPaintEnabled = gfxConfig::IsEnabled(Feature::OMTP); return NS_OK; } NS_IMETHODIMP GfxInfoBase::GetOffMainThreadPaintWorkerCount(int32_t* aOffMainThreadPaintWorkerCount)
--- a/widget/GfxInfoBase.h +++ b/widget/GfxInfoBase.h @@ -57,16 +57,17 @@ public: NS_IMETHOD GetFeatures(JSContext*, JS::MutableHandle<JS::Value>) override; NS_IMETHOD GetFeatureLog(JSContext*, JS::MutableHandle<JS::Value>) override; NS_IMETHOD GetActiveCrashGuards(JSContext*, JS::MutableHandle<JS::Value>) override; NS_IMETHOD GetContentBackend(nsAString & aContentBackend) override; NS_IMETHOD GetUsingGPUProcess(bool *aOutValue) override; NS_IMETHOD GetWebRenderEnabled(bool* aWebRenderEnabled) override; NS_IMETHOD GetIsHeadless(bool* aIsHeadless) override; NS_IMETHOD GetUsesTiling(bool* aUsesTiling) override; + NS_IMETHOD GetContentUsesTiling(bool* aUsesTiling) override; NS_IMETHOD GetOffMainThreadPaintEnabled(bool* aOffMainThreadPaintEnabled) override; NS_IMETHOD GetOffMainThreadPaintWorkerCount(int32_t* aOffMainThreadPaintWorkerCount) override; // Initialization function. If you override this, you must call this class's // version of Init first. // We need Init to be called separately from the constructor so we can // register as an observer after all derived classes have been constructed // and we know we have a non-zero refcount.
--- a/widget/nsIGfxInfo.idl +++ b/widget/nsIGfxInfo.idl @@ -21,16 +21,17 @@ interface nsIGfxInfo : nsISupports /* * These are valid across all platforms. */ readonly attribute DOMString ContentBackend; readonly attribute boolean WebRenderEnabled; readonly attribute boolean isHeadless; readonly attribute boolean UsesTiling; + readonly attribute boolean ContentUsesTiling; readonly attribute boolean OffMainThreadPaintEnabled; readonly attribute long OffMainThreadPaintWorkerCount; // XXX: Switch to a list of devices, rather than explicitly numbering them. /** * The name of the display adapter. */