From dcc3953291d5494242e76a71c43ba5b1f37ad9f1 Mon Sep 17 00:00:00 2001 From: David Keeler Date: Thu, 15 Jan 2015 11:01:10 -0800 Subject: [PATCH 01/74] bug 832837 - move insecure form submission warning from nsSecureBrowserUIImpl to the HTML form implementation r=mrbkap r=phlsa As a result, we can remove nsSecurityWarningDialogs completely, which this patch also does. --- CLOBBER | 2 +- dom/html/HTMLFormElement.cpp | 141 ++++++++-- dom/html/HTMLFormElement.h | 10 + security/manager/boot/public/moz.build | 1 - .../boot/public/nsISecurityWarningDialogs.idl | 32 --- security/manager/boot/src/moz.build | 1 - security/manager/boot/src/nsBOOTModule.cpp | 5 - .../boot/src/nsSecureBrowserUIImpl.cpp | 255 ------------------ .../manager/boot/src/nsSecureBrowserUIImpl.h | 26 -- .../boot/src/nsSecurityWarningDialogs.cpp | 162 ----------- .../boot/src/nsSecurityWarningDialogs.h | 45 ---- .../en-US/chrome/pipnss/security.properties | 7 - security/manager/locales/jar.mn | 1 - .../en-US/chrome/global/browser.properties | 4 + 14 files changed, 133 insertions(+), 559 deletions(-) delete mode 100644 security/manager/boot/public/nsISecurityWarningDialogs.idl delete mode 100644 security/manager/boot/src/nsSecurityWarningDialogs.cpp delete mode 100644 security/manager/boot/src/nsSecurityWarningDialogs.h delete mode 100644 security/manager/locales/en-US/chrome/pipnss/security.properties diff --git a/CLOBBER b/CLOBBER index f04b62fe5149..bb1befee7964 100644 --- a/CLOBBER +++ b/CLOBBER @@ -22,4 +22,4 @@ # changes to stick? As of bug 928195, this shouldn't be necessary! Please # don't change CLOBBER for WebIDL changes any more. -Bug 870366 - Blacklisting PREF_JS_EXPORTS in Makefile.ins (because of 852814) +bug 832837 removes nsISecurityWarningDialogs.idl, which requires a clobber according to bug 1114669 diff --git a/dom/html/HTMLFormElement.cpp b/dom/html/HTMLFormElement.cpp index 378a7f7e56e2..30c13d6fe6f6 100644 --- a/dom/html/HTMLFormElement.cpp +++ b/dom/html/HTMLFormElement.cpp @@ -20,7 +20,6 @@ #include "nsPresContext.h" #include "nsIDocument.h" #include "nsIFormControlFrame.h" -#include "nsISecureBrowserUI.h" #include "nsError.h" #include "nsContentUtils.h" #include "nsInterfaceHashtable.h" @@ -33,6 +32,7 @@ #include "mozilla/BinarySearch.h" // form submission +#include "mozilla/Telemetry.h" #include "nsIFormSubmitObserver.h" #include "nsIObserverService.h" #include "nsICategoryManager.h" @@ -45,6 +45,9 @@ #include "nsIDocShell.h" #include "nsFormData.h" #include "nsFormSubmissionConstants.h" +#include "nsIPromptService.h" +#include "nsISecurityUITelemetry.h" +#include "nsIStringBundle.h" // radio buttons #include "mozilla/dom/HTMLInputElement.h" @@ -858,6 +861,108 @@ HTMLFormElement::SubmitSubmission(nsFormSubmission* aFormSubmission) return rv; } +nsresult +HTMLFormElement::DoSecureToInsecureSubmitCheck(nsIURI* aActionURL, + bool* aCancelSubmit) +{ + *aCancelSubmit = false; + + // Only ask the user about posting from a secure URI to an insecure URI if + // this element is in the root document. When this is not the case, the mixed + // content blocker will take care of security for us. + nsIDocument* parent = OwnerDoc()->GetParentDocument(); + bool isRootDocument = (!parent || nsContentUtils::IsChromeDoc(parent)); + if (!isRootDocument) { + return NS_OK; + } + + nsIPrincipal* principal = NodePrincipal(); + if (!principal) { + *aCancelSubmit = true; + return NS_OK; + } + nsCOMPtr principalURI; + nsresult rv = principal->GetURI(getter_AddRefs(principalURI)); + if (NS_FAILED(rv)) { + return rv; + } + if (!principalURI) { + principalURI = OwnerDoc()->GetDocumentURI(); + } + bool formIsHTTPS; + rv = principalURI->SchemeIs("https", &formIsHTTPS); + if (NS_FAILED(rv)) { + return rv; + } + bool actionIsHTTPS; + rv = aActionURL->SchemeIs("https", &actionIsHTTPS); + if (NS_FAILED(rv)) { + return rv; + } + bool actionIsJS; + rv = aActionURL->SchemeIs("javascript", &actionIsJS); + if (NS_FAILED(rv)) { + return rv; + } + + if (!formIsHTTPS || actionIsHTTPS || actionIsJS) { + return NS_OK; + } + + nsCOMPtr promptSvc = + do_GetService("@mozilla.org/embedcomp/prompt-service;1"); + if (!promptSvc) { + return NS_ERROR_FAILURE; + } + nsCOMPtr stringBundle; + nsCOMPtr stringBundleService = + mozilla::services::GetStringBundleService(); + if (!stringBundleService) { + return NS_ERROR_FAILURE; + } + rv = stringBundleService->CreateBundle( + "chrome://global/locale/browser.properties", + getter_AddRefs(stringBundle)); + if (NS_FAILED(rv)) { + return rv; + } + nsAutoString title; + nsAutoString message; + nsAutoString cont; + stringBundle->GetStringFromName( + MOZ_UTF16("formPostSecureToInsecureWarning.title"), getter_Copies(title)); + stringBundle->GetStringFromName( + MOZ_UTF16("formPostSecureToInsecureWarning.message"), + getter_Copies(message)); + stringBundle->GetStringFromName( + MOZ_UTF16("formPostSecureToInsecureWarning.continue"), + getter_Copies(cont)); + int32_t buttonPressed; + bool checkState = false; // this is unused (ConfirmEx requires this parameter) + nsCOMPtr window = OwnerDoc()->GetWindow(); + rv = promptSvc->ConfirmEx(window, title.get(), message.get(), + (nsIPromptService::BUTTON_TITLE_IS_STRING * + nsIPromptService::BUTTON_POS_0) + + (nsIPromptService::BUTTON_TITLE_CANCEL * + nsIPromptService::BUTTON_POS_1), + cont.get(), nullptr, nullptr, nullptr, + &checkState, &buttonPressed); + if (NS_FAILED(rv)) { + return rv; + } + *aCancelSubmit = (buttonPressed == 1); + uint32_t telemetryBucket = + nsISecurityUITelemetry::WARNING_CONFIRM_POST_TO_INSECURE_FROM_SECURE; + mozilla::Telemetry::Accumulate(mozilla::Telemetry::SECURITY_UI, + telemetryBucket); + if (!*aCancelSubmit) { + // The user opted to continue, so note that in the next telemetry bucket. + mozilla::Telemetry::Accumulate(mozilla::Telemetry::SECURITY_UI, + telemetryBucket + 1); + } + return NS_OK; +} + nsresult HTMLFormElement::NotifySubmitObservers(nsIURI* aActionURL, bool* aCancelSubmit, @@ -872,28 +977,13 @@ HTMLFormElement::NotifySubmitObservers(nsIURI* aActionURL, NS_FIRST_FORMSUBMIT_CATEGORY); } - // XXXbz what do the submit observers actually want? The window - // of the document this is shown in? Or something else? - // sXBL/XBL2 issue - nsCOMPtr window = OwnerDoc()->GetWindow(); - - // Notify the secure browser UI, if any, that the form is being submitted. - nsCOMPtr docshell = OwnerDoc()->GetDocShell(); - if (docshell && !aEarlyNotify) { - nsCOMPtr secureUI; - docshell->GetSecurityUI(getter_AddRefs(secureUI)); - nsCOMPtr formSubmitObserver = - do_QueryInterface(secureUI); - if (formSubmitObserver) { - nsresult rv = formSubmitObserver->Notify(this, - window, - aActionURL, - aCancelSubmit); - NS_ENSURE_SUCCESS(rv, rv); - - if (*aCancelSubmit) { - return NS_OK; - } + if (!aEarlyNotify) { + nsresult rv = DoSecureToInsecureSubmitCheck(aActionURL, aCancelSubmit); + if (NS_FAILED(rv)) { + return rv; + } + if (*aCancelSubmit) { + return NS_OK; } } @@ -914,6 +1004,11 @@ HTMLFormElement::NotifySubmitObservers(nsIURI* aActionURL, nsCOMPtr inst; *aCancelSubmit = false; + // XXXbz what do the submit observers actually want? The window + // of the document this is shown in? Or something else? + // sXBL/XBL2 issue + nsCOMPtr window = OwnerDoc()->GetWindow(); + bool loop = true; while (NS_SUCCEEDED(theEnum->HasMoreElements(&loop)) && loop) { theEnum->GetNext(getter_AddRefs(inst)); diff --git a/dom/html/HTMLFormElement.h b/dom/html/HTMLFormElement.h index faf0cbd7c665..40883c6bdee4 100644 --- a/dom/html/HTMLFormElement.h +++ b/dom/html/HTMLFormElement.h @@ -495,6 +495,16 @@ protected: nsresult NotifySubmitObservers(nsIURI* aActionURL, bool* aCancelSubmit, bool aEarlyNotify); + /** + * If this form submission is secure -> insecure, ask the user if they want + * to continue. + * + * @param aActionURL the URL being submitted to + * @param aCancelSubmit out param: will be true if the user wants to cancel + */ + nsresult DoSecureToInsecureSubmitCheck(nsIURI* aActionURL, + bool* aCancelSubmit); + /** * Find form controls in this form with the correct value in the name * attribute. diff --git a/security/manager/boot/public/moz.build b/security/manager/boot/public/moz.build index 5f841e1c1d1c..b0879c6d99a8 100644 --- a/security/manager/boot/public/moz.build +++ b/security/manager/boot/public/moz.build @@ -8,7 +8,6 @@ XPIDL_SOURCES += [ 'nsIBufEntropyCollector.idl', 'nsICertBlocklist.idl', 'nsISecurityUITelemetry.idl', - 'nsISecurityWarningDialogs.idl', 'nsISSLStatusProvider.idl', ] diff --git a/security/manager/boot/public/nsISecurityWarningDialogs.idl b/security/manager/boot/public/nsISecurityWarningDialogs.idl deleted file mode 100644 index d6c812abf435..000000000000 --- a/security/manager/boot/public/nsISecurityWarningDialogs.idl +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsISupports.idl" - -interface nsIInterfaceRequestor; - -/** - * Functions that display warnings for transitions between secure - * and insecure pages, posts to insecure servers etc. - */ -[scriptable, uuid(a9561631-5964-4d3f-b372-9f23504054b1)] -interface nsISecurityWarningDialogs : nsISupports -{ - /** - * Inform the user: Although the currently displayed - * page was loaded using a secure connection, and the UI probably - * currently indicates a secure page, - * that information is being submitted to an insecure page. - * - * @param ctx A user interface context. - * - * @return true if the user confirms to submit. - */ - boolean confirmPostToInsecureFromSecure(in nsIInterfaceRequestor ctx); -}; - -%{C++ -#define NS_SECURITYWARNINGDIALOGS_CONTRACTID "@mozilla.org/nsSecurityWarningDialogs;1" -%} diff --git a/security/manager/boot/src/moz.build b/security/manager/boot/src/moz.build index 71078d16f0c6..e181f84ff673 100644 --- a/security/manager/boot/src/moz.build +++ b/security/manager/boot/src/moz.build @@ -15,7 +15,6 @@ UNIFIED_SOURCES += [ 'nsEntropyCollector.cpp', 'nsSecureBrowserUIImpl.cpp', 'nsSecurityHeaderParser.cpp', - 'nsSecurityWarningDialogs.cpp', 'nsSiteSecurityService.cpp', 'PublicKeyPinningService.cpp', 'RootCertificateTelemetryUtils.cpp', diff --git a/security/manager/boot/src/nsBOOTModule.cpp b/security/manager/boot/src/nsBOOTModule.cpp index 62e1b6374a3b..52f1a5d28939 100644 --- a/security/manager/boot/src/nsBOOTModule.cpp +++ b/security/manager/boot/src/nsBOOTModule.cpp @@ -8,24 +8,20 @@ #include "CertBlocklist.h" #include "nsEntropyCollector.h" #include "nsSecureBrowserUIImpl.h" -#include "nsSecurityWarningDialogs.h" #include "nsSiteSecurityService.h" NS_GENERIC_FACTORY_CONSTRUCTOR(nsEntropyCollector) NS_GENERIC_FACTORY_CONSTRUCTOR(nsSecureBrowserUIImpl) NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(CertBlocklist, Init) -NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSecurityWarningDialogs, Init) NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSiteSecurityService, Init) NS_DEFINE_NAMED_CID(NS_ENTROPYCOLLECTOR_CID); -NS_DEFINE_NAMED_CID(NS_SECURITYWARNINGDIALOGS_CID); NS_DEFINE_NAMED_CID(NS_SECURE_BROWSER_UI_CID); NS_DEFINE_NAMED_CID(NS_SITE_SECURITY_SERVICE_CID); NS_DEFINE_NAMED_CID(NS_CERT_BLOCKLIST_CID); static const mozilla::Module::CIDEntry kBOOTCIDs[] = { { &kNS_ENTROPYCOLLECTOR_CID, false, nullptr, nsEntropyCollectorConstructor }, - { &kNS_SECURITYWARNINGDIALOGS_CID, false, nullptr, nsSecurityWarningDialogsConstructor }, { &kNS_SECURE_BROWSER_UI_CID, false, nullptr, nsSecureBrowserUIImplConstructor }, { &kNS_SITE_SECURITY_SERVICE_CID, false, nullptr, nsSiteSecurityServiceConstructor }, { &kNS_CERT_BLOCKLIST_CID, false, nullptr, CertBlocklistConstructor}, @@ -34,7 +30,6 @@ static const mozilla::Module::CIDEntry kBOOTCIDs[] = { static const mozilla::Module::ContractIDEntry kBOOTContracts[] = { { NS_ENTROPYCOLLECTOR_CONTRACTID, &kNS_ENTROPYCOLLECTOR_CID }, - { NS_SECURITYWARNINGDIALOGS_CONTRACTID, &kNS_SECURITYWARNINGDIALOGS_CID }, { NS_SECURE_BROWSER_UI_CONTRACTID, &kNS_SECURE_BROWSER_UI_CID }, { NS_SSSERVICE_CONTRACTID, &kNS_SITE_SECURITY_SERVICE_CID }, { NS_CERTBLOCKLIST_CONTRACTID, &kNS_CERT_BLOCKLIST_CID }, diff --git a/security/manager/boot/src/nsSecureBrowserUIImpl.cpp b/security/manager/boot/src/nsSecureBrowserUIImpl.cpp index 132855f3ebb4..a5b6bd9907db 100644 --- a/security/manager/boot/src/nsSecureBrowserUIImpl.cpp +++ b/security/manager/boot/src/nsSecureBrowserUIImpl.cpp @@ -9,17 +9,13 @@ #include "nsISecureBrowserUI.h" #include "nsSecureBrowserUIImpl.h" #include "nsCOMPtr.h" -#include "nsIInterfaceRequestor.h" -#include "nsIInterfaceRequestorUtils.h" #include "nsIServiceManager.h" #include "nsCURILoader.h" #include "nsIDocShell.h" #include "nsIDocShellTreeItem.h" #include "nsIDocument.h" -#include "nsIPrincipal.h" #include "nsIDOMElement.h" #include "nsPIDOMWindow.h" -#include "nsIContent.h" #include "nsIWebProgress.h" #include "nsIWebProgressListener.h" #include "nsIChannel.h" @@ -31,9 +27,6 @@ #include "nsISSLStatus.h" #include "nsIURI.h" #include "nsISecurityEventSink.h" -#include "nsIPrompt.h" -#include "nsIFormSubmitObserver.h" -#include "nsISecurityWarningDialogs.h" #include "nsISecurityInfoProvider.h" #include "imgIRequest.h" #include "nsThreadUtils.h" @@ -141,7 +134,6 @@ nsSecureBrowserUIImpl::~nsSecureBrowserUIImpl() NS_IMPL_ISUPPORTS(nsSecureBrowserUIImpl, nsISecureBrowserUI, nsIWebProgressListener, - nsIFormSubmitObserver, nsISupportsWeakReference, nsISSLStatusProvider) @@ -311,25 +303,6 @@ nsSecureBrowserUIImpl::SetDocShell(nsIDocShell *aDocShell) return rv; } -static nsresult IsChildOfDomWindow(nsIDOMWindow *parent, nsIDOMWindow *child, - bool* value) -{ - *value = false; - - if (parent == child) { - *value = true; - return NS_OK; - } - - nsCOMPtr childsParent; - child->GetParent(getter_AddRefs(childsParent)); - - if (childsParent && childsParent.get() != child) - IsChildOfDomWindow(parent, childsParent, value); - - return NS_OK; -} - static uint32_t GetSecurityStateFromSecurityInfoAndRequest(nsISupports* info, nsIRequest* request) { @@ -383,72 +356,6 @@ static uint32_t GetSecurityStateFromSecurityInfoAndRequest(nsISupports* info, } -NS_IMETHODIMP -nsSecureBrowserUIImpl::Notify(nsIDOMHTMLFormElement* aDOMForm, - nsIDOMWindow* aWindow, nsIURI* actionURL, - bool* cancelSubmit) -{ - // Return NS_OK unless we want to prevent this form from submitting. - *cancelSubmit = false; - if (!aWindow || !actionURL || !aDOMForm) - return NS_OK; - - nsCOMPtr formNode = do_QueryInterface(aDOMForm); - - nsCOMPtr document = formNode->GetComposedDoc(); - if (!document) return NS_OK; - - nsIPrincipal *principal = formNode->NodePrincipal(); - - if (!principal) - { - *cancelSubmit = true; - return NS_OK; - } - - nsCOMPtr formURL; - if (NS_FAILED(principal->GetURI(getter_AddRefs(formURL))) || - !formURL) - { - formURL = document->GetDocumentURI(); - } - - nsCOMPtr postingWindow = - do_QueryInterface(document->GetWindow()); - // We can't find this document's window, cancel it. - if (!postingWindow) - { - NS_WARNING("If you see this and can explain why it should be allowed, note in Bug 332324"); - *cancelSubmit = true; - return NS_OK; - } - - nsCOMPtr window; - { - ReentrantMonitorAutoEnter lock(mReentrantMonitor); - window = do_QueryReferent(mWindow); - - // The window was destroyed, so we assume no form was submitted within it. - if (!window) - return NS_OK; - } - - bool isChild; - IsChildOfDomWindow(window, postingWindow, &isChild); - - // This notify call is not for our window, ignore it. - if (!isChild) - return NS_OK; - - bool okayToPost; - nsresult res = CheckPost(formURL, actionURL, &okayToPost); - - if (NS_SUCCEEDED(res) && !okayToPost) - *cancelSubmit = true; - - return res; -} - // nsIWebProgressListener NS_IMETHODIMP nsSecureBrowserUIImpl::OnProgressChange(nsIWebProgress* aWebProgress, @@ -1508,165 +1415,3 @@ nsSecureBrowserUIImpl::GetSSLStatus(nsISSLStatus** _result) return NS_OK; } - -nsresult -nsSecureBrowserUIImpl::IsURLHTTPS(nsIURI* aURL, bool* value) -{ - *value = false; - - if (!aURL) - return NS_OK; - - return aURL->SchemeIs("https", value); -} - -nsresult -nsSecureBrowserUIImpl::IsURLJavaScript(nsIURI* aURL, bool* value) -{ - *value = false; - - if (!aURL) - return NS_OK; - - return aURL->SchemeIs("javascript", value); -} - -nsresult -nsSecureBrowserUIImpl::CheckPost(nsIURI *formURL, nsIURI *actionURL, bool *okayToPost) -{ - bool formSecure, actionSecure, actionJavaScript; - *okayToPost = true; - - nsresult rv = IsURLHTTPS(formURL, &formSecure); - if (NS_FAILED(rv)) - return rv; - - rv = IsURLHTTPS(actionURL, &actionSecure); - if (NS_FAILED(rv)) - return rv; - - rv = IsURLJavaScript(actionURL, &actionJavaScript); - if (NS_FAILED(rv)) - return rv; - - // If we are posting to a secure link, all is okay. - // It doesn't matter whether the currently viewed page is secure or not, - // because the data will be sent to a secure URL. - if (actionSecure) { - return NS_OK; - } - - // Action is a JavaScript call, not an actual post. That's okay too. - if (actionJavaScript) { - return NS_OK; - } - - // posting to insecure webpage from a secure webpage. - if (formSecure) { - *okayToPost = ConfirmPostToInsecureFromSecure(); - } - - return NS_OK; -} - -// -// Implementation of an nsIInterfaceRequestor for use -// as context for NSS calls -// -class nsUIContext : public nsIInterfaceRequestor -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIINTERFACEREQUESTOR - - explicit nsUIContext(nsIDOMWindow *window); - -protected: - virtual ~nsUIContext(); - -private: - nsCOMPtr mWindow; -}; - -NS_IMPL_ISUPPORTS(nsUIContext, nsIInterfaceRequestor) - -nsUIContext::nsUIContext(nsIDOMWindow *aWindow) -: mWindow(aWindow) -{ -} - -nsUIContext::~nsUIContext() -{ -} - -/* void getInterface (in nsIIDRef uuid, [iid_is (uuid), retval] out nsQIResult result); */ -NS_IMETHODIMP nsUIContext::GetInterface(const nsIID & uuid, void * *result) -{ - NS_ENSURE_TRUE(mWindow, NS_ERROR_FAILURE); - nsresult rv; - - if (uuid.Equals(NS_GET_IID(nsIPrompt))) { - nsCOMPtr window = do_QueryInterface(mWindow, &rv); - if (NS_FAILED(rv)) return rv; - - nsIPrompt *prompt; - - rv = window->GetPrompter(&prompt); - *result = prompt; - } else if (uuid.Equals(NS_GET_IID(nsIDOMWindow))) { - *result = mWindow; - NS_ADDREF ((nsISupports*) *result); - rv = NS_OK; - } else { - rv = NS_ERROR_NO_INTERFACE; - } - - return rv; -} - -bool -nsSecureBrowserUIImpl::GetNSSDialogs(nsCOMPtr & dialogs, - nsCOMPtr & ctx) -{ - if (!NS_IsMainThread()) { - NS_ERROR("nsSecureBrowserUIImpl::GetNSSDialogs called off the main thread"); - return false; - } - - dialogs = do_GetService(NS_SECURITYWARNINGDIALOGS_CONTRACTID); - if (!dialogs) - return false; - - nsCOMPtr window; - { - ReentrantMonitorAutoEnter lock(mReentrantMonitor); - window = do_QueryReferent(mWindow); - NS_ASSERTION(window, "Window has gone away?!"); - } - ctx = new nsUIContext(window); - - return true; -} - -/** - * ConfirmPostToInsecureFromSecure - returns true if - * the user approves the submit (or doesn't care). - * returns false on errors. - */ -bool nsSecureBrowserUIImpl:: -ConfirmPostToInsecureFromSecure() -{ - nsCOMPtr dialogs; - nsCOMPtr ctx; - - if (!GetNSSDialogs(dialogs, ctx)) { - return false; // Should this allow true for unimplemented? - } - - bool result; - - nsresult rv = dialogs->ConfirmPostToInsecureFromSecure(ctx, &result); - if (NS_FAILED(rv)) return false; - - return result; -} diff --git a/security/manager/boot/src/nsSecureBrowserUIImpl.h b/security/manager/boot/src/nsSecureBrowserUIImpl.h index 5f7b4edda05c..4dd0792b6ed2 100644 --- a/security/manager/boot/src/nsSecureBrowserUIImpl.h +++ b/security/manager/boot/src/nsSecureBrowserUIImpl.h @@ -14,12 +14,10 @@ #include "nsString.h" #include "nsIDOMElement.h" #include "nsIDOMWindow.h" -#include "nsIDOMHTMLFormElement.h" #include "nsISecureBrowserUI.h" #include "nsIDocShell.h" #include "nsIDocShellTreeItem.h" #include "nsIWebProgressListener.h" -#include "nsIFormSubmitObserver.h" #include "nsIURI.h" #include "nsISecurityEventSink.h" #include "nsWeakReference.h" @@ -29,10 +27,7 @@ #include "nsINetUtil.h" class nsISSLStatus; -class nsITransportSecurityInfo; -class nsISecurityWarningDialogs; class nsIChannel; -class nsIInterfaceRequestor; #define NS_SECURE_BROWSER_UI_CID \ { 0xcc75499a, 0x1dd1, 0x11b2, {0x8a, 0x82, 0xca, 0x41, 0x0a, 0xc9, 0x07, 0xb8}} @@ -40,7 +35,6 @@ class nsIInterfaceRequestor; class nsSecureBrowserUIImpl : public nsISecureBrowserUI, public nsIWebProgressListener, - public nsIFormSubmitObserver, public nsSupportsWeakReference, public nsISSLStatusProvider { @@ -51,14 +45,8 @@ public: NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIWEBPROGRESSLISTENER NS_DECL_NSISECUREBROWSERUI - NS_DECL_NSISSLSTATUSPROVIDER - NS_IMETHOD Notify(nsIDOMHTMLFormElement* formNode, nsIDOMWindow* window, - nsIURI *actionURL, bool* cancelSubmit) MOZ_OVERRIDE; - NS_IMETHOD NotifyInvalidSubmit(nsIDOMHTMLFormElement* formNode, - nsIArray* invalidElements) MOZ_OVERRIDE { return NS_OK; } - protected: virtual ~nsSecureBrowserUIImpl(); @@ -112,20 +100,6 @@ protected: nsCOMPtr mSSLStatus; nsCOMPtr mCurrentToplevelSecurityInfo; - nsresult CheckPost(nsIURI *formURI, nsIURI *actionURL, bool *okayToPost); - nsresult IsURLHTTPS(nsIURI* aURL, bool *value); - nsresult IsURLJavaScript(nsIURI* aURL, bool *value); - - bool ConfirmEnteringSecure(); - bool ConfirmEnteringWeak(); - bool ConfirmLeavingSecure(); - bool ConfirmMixedMode(); - bool ConfirmPostToInsecure(); - bool ConfirmPostToInsecureFromSecure(); - - bool GetNSSDialogs(nsCOMPtr & dialogs, - nsCOMPtr & window); - PLDHashTable mTransferringRequests; }; diff --git a/security/manager/boot/src/nsSecurityWarningDialogs.cpp b/security/manager/boot/src/nsSecurityWarningDialogs.cpp deleted file mode 100644 index 110afc7b92dd..000000000000 --- a/security/manager/boot/src/nsSecurityWarningDialogs.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsSecurityWarningDialogs.h" -#include "nsIComponentManager.h" -#include "nsIServiceManager.h" -#include "nsReadableUtils.h" -#include "nsString.h" -#include "nsIPrompt.h" -#include "nsIInterfaceRequestor.h" -#include "nsIInterfaceRequestorUtils.h" -#include "nsIPrefService.h" -#include "nsIPrefBranch.h" -#include "nsThreadUtils.h" - -#include "mozilla/Telemetry.h" -#include "nsISecurityUITelemetry.h" - -NS_IMPL_ISUPPORTS(nsSecurityWarningDialogs, nsISecurityWarningDialogs) - -#define STRING_BUNDLE_URL "chrome://pipnss/locale/security.properties" - -nsSecurityWarningDialogs::nsSecurityWarningDialogs() -{ -} - -nsSecurityWarningDialogs::~nsSecurityWarningDialogs() -{ -} - -nsresult -nsSecurityWarningDialogs::Init() -{ - nsresult rv; - - mPrefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr service = - do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv); - if (NS_FAILED(rv)) return rv; - - rv = service->CreateBundle(STRING_BUNDLE_URL, - getter_AddRefs(mStringBundle)); - return rv; -} - -NS_IMETHODIMP -nsSecurityWarningDialogs::ConfirmPostToInsecureFromSecure(nsIInterfaceRequestor *ctx, bool* _result) -{ - nsresult rv; - - // The Telemetry clickthrough constant is 1 more than the constant for the dialog. - rv = ConfirmDialog(ctx, nullptr, // No preference for this one - it's too important - MOZ_UTF16("PostToInsecureFromSecureMessage"), - nullptr, - nsISecurityUITelemetry::WARNING_CONFIRM_POST_TO_INSECURE_FROM_SECURE, - _result); - - return rv; -} - -nsresult -nsSecurityWarningDialogs::ConfirmDialog(nsIInterfaceRequestor *ctx, const char *prefName, - const char16_t *messageName, - const char16_t *showAgainName, - const uint32_t aBucket, - bool* _result) -{ - nsresult rv; - - // Get user's preference for this alert - // prefName, showAgainName are null if there is no preference for this dialog - bool prefValue = true; - - if (prefName) { - rv = mPrefBranch->GetBoolPref(prefName, &prefValue); - if (NS_FAILED(rv)) prefValue = true; - } - - // Stop if confirm is not requested - if (!prefValue) { - *_result = true; - return NS_OK; - } - - MOZ_ASSERT(NS_IsMainThread()); - mozilla::Telemetry::Accumulate(mozilla::Telemetry::SECURITY_UI, aBucket); - // See AlertDialog() for a description of how showOnce works. - nsAutoCString showOncePref(prefName); - showOncePref += ".show_once"; - - bool showOnce = false; - mPrefBranch->GetBoolPref(showOncePref.get(), &showOnce); - - if (showOnce) - prefValue = false; - - // Get Prompt to use - nsCOMPtr prompt = do_GetInterface(ctx); - if (!prompt) return NS_ERROR_FAILURE; - - // Get messages strings from localization file - nsXPIDLString windowTitle, message, alertMe, cont; - - mStringBundle->GetStringFromName(MOZ_UTF16("Title"), - getter_Copies(windowTitle)); - mStringBundle->GetStringFromName(messageName, - getter_Copies(message)); - if (showAgainName) { - mStringBundle->GetStringFromName(showAgainName, - getter_Copies(alertMe)); - } - mStringBundle->GetStringFromName(MOZ_UTF16("Continue"), - getter_Copies(cont)); - // alertMe is allowed to be null - if (!windowTitle || !message || !cont) return NS_ERROR_FAILURE; - - // Replace # characters with newlines to lay out the dialog. - char16_t* msgchars = message.BeginWriting(); - - uint32_t i = 0; - for (i = 0; msgchars[i] != '\0'; i++) { - if (msgchars[i] == '#') { - msgchars[i] = '\n'; - } - } - - int32_t buttonPressed; - - rv = prompt->ConfirmEx(windowTitle, - message, - (nsIPrompt::BUTTON_TITLE_IS_STRING * nsIPrompt::BUTTON_POS_0) + - (nsIPrompt::BUTTON_TITLE_CANCEL * nsIPrompt::BUTTON_POS_1), - cont, - nullptr, - nullptr, - alertMe, - &prefValue, - &buttonPressed); - - if (NS_FAILED(rv)) return rv; - - *_result = (buttonPressed != 1); - if (*_result) { - // For confirmation dialogs, the clickthrough constant is 1 more - // than the constant for the dialog. - mozilla::Telemetry::Accumulate(mozilla::Telemetry::SECURITY_UI, aBucket + 1); - } - - if (!prefValue && prefName) { - mPrefBranch->SetBoolPref(prefName, false); - } else if (prefValue && showOnce) { - mPrefBranch->SetBoolPref(showOncePref.get(), false); - } - - return rv; -} - diff --git a/security/manager/boot/src/nsSecurityWarningDialogs.h b/security/manager/boot/src/nsSecurityWarningDialogs.h deleted file mode 100644 index 0a9313bae92c..000000000000 --- a/security/manager/boot/src/nsSecurityWarningDialogs.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nsSecurityWarningDialogs_h -#define nsSecurityWarningDialogs_h - -#include "nsISecurityWarningDialogs.h" -#include "nsIPrefBranch.h" -#include "nsIStringBundle.h" -#include "nsCOMPtr.h" - -class nsSecurityWarningDialogs : public nsISecurityWarningDialogs -{ -public: - NS_DECL_THREADSAFE_ISUPPORTS - NS_DECL_NSISECURITYWARNINGDIALOGS - - nsSecurityWarningDialogs(); - - nsresult Init(); - -protected: - virtual ~nsSecurityWarningDialogs(); - - nsresult AlertDialog(nsIInterfaceRequestor *ctx, const char *prefName, - const char16_t *messageName, - const char16_t *showAgainName, - bool aAsync, const uint32_t aBucket); - nsresult ConfirmDialog(nsIInterfaceRequestor *ctx, const char *prefName, - const char16_t *messageName, - const char16_t *showAgainName, const uint32_t aBucket, - bool* _result); - nsCOMPtr mStringBundle; - nsCOMPtr mPrefBranch; -}; - -#define NS_SECURITYWARNINGDIALOGS_CID \ - { /* 8d995d4f-adcc-4159-b7f1-e94af72eeb88 */ \ - 0x8d995d4f, 0xadcc, 0x4159, \ - {0xb7, 0xf1, 0xe9, 0x4a, 0xf7, 0x2e, 0xeb, 0x88} } - -#endif diff --git a/security/manager/locales/en-US/chrome/pipnss/security.properties b/security/manager/locales/en-US/chrome/pipnss/security.properties deleted file mode 100644 index 50af92694e0e..000000000000 --- a/security/manager/locales/en-US/chrome/pipnss/security.properties +++ /dev/null @@ -1,7 +0,0 @@ -# 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/. - -Title=Security Warning -PostToInsecureFromSecureMessage=Although this page is encrypted, the information you have entered is to be sent over an unencrypted connection and could easily be read by a third party.##Are you sure you want to continue sending this information?## -Continue=Continue diff --git a/security/manager/locales/jar.mn b/security/manager/locales/jar.mn index 66c1535f3b66..9b5c2da4461d 100644 --- a/security/manager/locales/jar.mn +++ b/security/manager/locales/jar.mn @@ -9,7 +9,6 @@ % locale pippki @AB_CD@ %locale/@AB_CD@/pippki/ locale/@AB_CD@/pipnss/pipnss.properties (%chrome/pipnss/pipnss.properties) locale/@AB_CD@/pipnss/nsserrors.properties (%chrome/pipnss/nsserrors.properties) - locale/@AB_CD@/pipnss/security.properties (%chrome/pipnss/security.properties) locale/@AB_CD@/pippki/pippki.dtd (%chrome/pippki/pippki.dtd) locale/@AB_CD@/pippki/pippki.properties (%chrome/pippki/pippki.properties) locale/@AB_CD@/pippki/certManager.dtd (%chrome/pippki/certManager.dtd) diff --git a/toolkit/locales/en-US/chrome/global/browser.properties b/toolkit/locales/en-US/chrome/global/browser.properties index 0e5409fd1cc0..2b315062918a 100644 --- a/toolkit/locales/en-US/chrome/global/browser.properties +++ b/toolkit/locales/en-US/chrome/global/browser.properties @@ -8,3 +8,7 @@ browsewithcaret.checkLabel=Pressing F7 turns Caret Browsing on or off. This feat browsewithcaret.checkButtonLabel=Yes plainText.wordWrap=Wrap Long Lines + +formPostSecureToInsecureWarning.title = Security Warning +formPostSecureToInsecureWarning.message = The information you have entered on this page will be sent over an insecure connection and could be read by a third party.\n\nAre you sure you want to send this information? +formPostSecureToInsecureWarning.continue = Continue From c73ec42d2d80af73b32b762c9e928354754d5f75 Mon Sep 17 00:00:00 2001 From: David Zbarsky Date: Wed, 4 Feb 2015 15:21:03 -0500 Subject: [PATCH 02/74] Bug 1125040: Use LayoutDeviceIntPoint for nsIWidget::WidgetToScreen r=botond --- accessible/generic/HyperTextAccessible.cpp | 2 +- dom/base/nsDOMWindowUtils.cpp | 3 +-- dom/base/nsQueryContentEventResult.cpp | 4 ++-- dom/events/ContentEventHandler.cpp | 8 +++----- dom/events/Event.cpp | 3 +-- dom/events/EventStateManager.cpp | 21 ++++++++----------- dom/events/IMEContentObserver.cpp | 9 ++++---- dom/events/UIEvent.h | 3 +-- dom/events/WheelHandlingHelper.cpp | 4 ++-- dom/plugins/base/nsPluginInstanceOwner.cpp | 3 +-- embedding/browser/nsDocShellTreeOwner.cpp | 2 +- gfx/tests/gtest/TestCompositor.cpp | 2 +- layout/base/PositionedEventTargeting.cpp | 4 ++-- layout/base/nsLayoutUtils.cpp | 24 +++++++++++----------- layout/base/nsLayoutUtils.h | 7 ++++--- layout/base/nsPresShell.cpp | 4 ++-- layout/generic/nsFrame.cpp | 2 +- layout/xul/nsResizerFrame.cpp | 6 ++---- layout/xul/nsXULPopupManager.cpp | 2 +- view/nsView.cpp | 2 +- widget/PuppetWidget.h | 4 ++-- widget/android/AndroidJavaWrappers.cpp | 7 +++---- widget/android/nsWindow.cpp | 9 ++++---- widget/android/nsWindow.h | 2 +- widget/cocoa/nsChildView.h | 2 +- widget/cocoa/nsChildView.mm | 10 ++++----- widget/cocoa/nsCocoaWindow.h | 2 +- widget/cocoa/nsCocoaWindow.mm | 6 +++--- widget/gonk/nsWindow.cpp | 4 ++-- widget/gonk/nsWindow.h | 2 +- widget/gtk/nsDragService.cpp | 2 +- widget/gtk/nsWindow.cpp | 23 +++++++++------------ widget/gtk/nsWindow.h | 4 ++-- widget/nsIWidget.h | 8 ++++++-- widget/qt/nsWindow.cpp | 4 ++-- widget/qt/nsWindow.h | 2 +- widget/windows/nsIMM32Handler.cpp | 8 ++++---- widget/windows/nsTextStore.cpp | 8 ++++---- widget/windows/nsWindow.cpp | 8 ++++---- widget/windows/nsWindow.h | 2 +- widget/windows/winrt/MetroWidget.cpp | 4 ++-- widget/windows/winrt/MetroWidget.h | 2 +- 42 files changed, 113 insertions(+), 125 deletions(-) diff --git a/accessible/generic/HyperTextAccessible.cpp b/accessible/generic/HyperTextAccessible.cpp index 3d394e24a0fc..5681aa01331e 100644 --- a/accessible/generic/HyperTextAccessible.cpp +++ b/accessible/generic/HyperTextAccessible.cpp @@ -1344,7 +1344,7 @@ HyperTextAccessible::GetCaretRect(nsIWidget** aWidget) nsIntRect caretRect; caretRect = rect.ToOutsidePixels(frame->PresContext()->AppUnitsPerDevPixel()); // ((content screen origin) - (content offset in the widget)) = widget origin on the screen - caretRect.MoveBy((*aWidget)->WidgetToScreenOffset() - (*aWidget)->GetClientOffset()); + caretRect.MoveBy((*aWidget)->WidgetToScreenOffsetUntyped() - (*aWidget)->GetClientOffset()); // Correct for character size, so that caret always matches the size of // the character. This is important for font size transitions, and is diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 32662d687f3e..07f45b1f2ec8 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -2195,8 +2195,7 @@ nsDOMWindowUtils::SendQueryContentEvent(uint32_t aType, } } - pt += LayoutDeviceIntPoint::FromUntyped( - widget->WidgetToScreenOffset() - targetWidget->WidgetToScreenOffset()); + pt += widget->WidgetToScreenOffset() - targetWidget->WidgetToScreenOffset(); WidgetQueryContentEvent queryEvent(true, aType, targetWidget); InitEvent(queryEvent, &pt); diff --git a/dom/base/nsQueryContentEventResult.cpp b/dom/base/nsQueryContentEventResult.cpp index bd2b7aee63b4..c451952a03f9 100644 --- a/dom/base/nsQueryContentEventResult.cpp +++ b/dom/base/nsQueryContentEventResult.cpp @@ -147,7 +147,7 @@ nsQueryContentEventResult::SetEventResult(nsIWidget* aWidget, } // Convert the top widget related coordinates to the given widget's. - nsIntPoint offset = + LayoutDeviceIntPoint offset = aWidget->WidgetToScreenOffset() - topWidget->WidgetToScreenOffset(); - mRect.MoveBy(-offset); + mRect.MoveBy(-LayoutDeviceIntPoint::ToUntyped(offset)); } diff --git a/dom/events/ContentEventHandler.cpp b/dom/events/ContentEventHandler.cpp index f5e83a2e89b2..3c3665a50a93 100644 --- a/dom/events/ContentEventHandler.cpp +++ b/dom/events/ContentEventHandler.cpp @@ -1149,9 +1149,8 @@ ContentEventHandler::OnQueryCharacterAtPoint(WidgetQueryContentEvent* aEvent) eventOnRoot.mUseNativeLineBreak = aEvent->mUseNativeLineBreak; eventOnRoot.refPoint = aEvent->refPoint; if (rootWidget != aEvent->widget) { - eventOnRoot.refPoint += LayoutDeviceIntPoint::FromUntyped( - aEvent->widget->WidgetToScreenOffset() - - rootWidget->WidgetToScreenOffset()); + eventOnRoot.refPoint += aEvent->widget->WidgetToScreenOffset() - + rootWidget->WidgetToScreenOffset(); } nsPoint ptInRoot = nsLayoutUtils::GetEventCoordinatesRelativeTo(&eventOnRoot, rootFrame); @@ -1214,8 +1213,7 @@ ContentEventHandler::OnQueryDOMWidgetHittest(WidgetQueryContentEvent* aEvent) nsIFrame* docFrame = mPresShell->GetRootFrame(); NS_ENSURE_TRUE(docFrame, NS_ERROR_FAILURE); - LayoutDeviceIntPoint eventLoc = aEvent->refPoint + - LayoutDeviceIntPoint::FromUntyped(aEvent->widget->WidgetToScreenOffset()); + LayoutDeviceIntPoint eventLoc = aEvent->refPoint + aEvent->widget->WidgetToScreenOffset(); nsIntRect docFrameRect = docFrame->GetScreenRect(); // Returns CSS pixels CSSIntPoint eventLocCSS( mPresContext->DevPixelsToIntCSSPixels(eventLoc.x) - docFrameRect.x, diff --git a/dom/events/Event.cpp b/dom/events/Event.cpp index e7d967814d34..04dbbf56b062 100644 --- a/dom/events/Event.cpp +++ b/dom/events/Event.cpp @@ -902,8 +902,7 @@ Event::GetScreenCoords(nsPresContext* aPresContext, return LayoutDeviceIntPoint::ToUntyped(aPoint); } - LayoutDeviceIntPoint offset = aPoint + - LayoutDeviceIntPoint::FromUntyped(guiEvent->widget->WidgetToScreenOffset()); + LayoutDeviceIntPoint offset = aPoint + guiEvent->widget->WidgetToScreenOffset(); nscoord factor = aPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom(); return nsIntPoint(nsPresContext::AppUnitsToIntCSSPixels(offset.x * factor), diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp index f30e9d7f4594..32a14b9721bd 100644 --- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -1505,8 +1505,7 @@ EventStateManager::BeginTrackingDragGesture(nsPresContext* aPresContext, // Note that |inDownEvent| could be either a mouse down event or a // synthesized mouse move event. - mGestureDownPoint = inDownEvent->refPoint + - LayoutDeviceIntPoint::FromUntyped(inDownEvent->widget->WidgetToScreenOffset()); + mGestureDownPoint = inDownEvent->refPoint + inDownEvent->widget->WidgetToScreenOffset(); inDownFrame->GetContentForEvent(inDownEvent, getter_AddRefs(mGestureDownContent)); @@ -1544,8 +1543,7 @@ EventStateManager::FillInEventFromGestureDown(WidgetMouseEvent* aEvent) // Set the coordinates in the new event to the coordinates of // the old event, adjusted for the fact that the widget might be // different - aEvent->refPoint = mGestureDownPoint - - LayoutDeviceIntPoint::FromUntyped(aEvent->widget->WidgetToScreenOffset()); + aEvent->refPoint = mGestureDownPoint - aEvent->widget->WidgetToScreenOffset(); aEvent->modifiers = mGestureModifiers; aEvent->buttons = mGestureDownButtons; } @@ -1601,8 +1599,7 @@ EventStateManager::GenerateDragGesture(nsPresContext* aPresContext, } // fire drag gesture if mouse has moved enough - LayoutDeviceIntPoint pt = aEvent->refPoint + - LayoutDeviceIntPoint::FromUntyped(aEvent->widget->WidgetToScreenOffset()); + LayoutDeviceIntPoint pt = aEvent->refPoint + aEvent->widget->WidgetToScreenOffset(); LayoutDeviceIntPoint distance = pt - mGestureDownPoint; if (Abs(distance.x) > AssertedCast(pixelThresholdX) || Abs(distance.y) > AssertedCast(pixelThresholdY)) { @@ -3216,9 +3213,9 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext, WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent(); event.refPoint = mouseEvent->refPoint; if (mouseEvent->widget) { - event.refPoint += LayoutDeviceIntPoint::FromUntyped(mouseEvent->widget->WidgetToScreenOffset()); + event.refPoint += mouseEvent->widget->WidgetToScreenOffset(); } - event.refPoint -= LayoutDeviceIntPoint::FromUntyped(widget->WidgetToScreenOffset()); + event.refPoint -= widget->WidgetToScreenOffset(); event.modifiers = mouseEvent->modifiers; event.buttons = mouseEvent->buttons; event.inputSource = mouseEvent->inputSource; @@ -4023,8 +4020,8 @@ EventStateManager::GenerateMouseEnterExit(WidgetMouseEvent* aMouseEvent) // in the other branch here. sSynthCenteringPoint = center; aMouseEvent->widget->SynthesizeNativeMouseMove( - LayoutDeviceIntPoint::ToUntyped(center) + - aMouseEvent->widget->WidgetToScreenOffset()); + LayoutDeviceIntPoint::ToUntyped(center + + aMouseEvent->widget->WidgetToScreenOffset())); } else if (aMouseEvent->refPoint == sSynthCenteringPoint) { // This is the "synthetic native" event we dispatched to re-center the // pointer. Cancel it so we don't expose the centering move to content. @@ -4160,7 +4157,7 @@ EventStateManager::SetPointerLock(nsIWidget* aWidget, aWidget, mPresContext); aWidget->SynthesizeNativeMouseMove( - LayoutDeviceIntPoint::ToUntyped(sLastRefPoint) + aWidget->WidgetToScreenOffset()); + LayoutDeviceIntPoint::ToUntyped(sLastRefPoint + aWidget->WidgetToScreenOffset())); // Retarget all events to this element via capture. nsIPresShell::SetCapturingContent(aElement, CAPTURE_POINTERLOCK); @@ -4176,7 +4173,7 @@ EventStateManager::SetPointerLock(nsIWidget* aWidget, // no movement. sLastRefPoint = mPreLockPoint; aWidget->SynthesizeNativeMouseMove( - LayoutDeviceIntPoint::ToUntyped(mPreLockPoint) + aWidget->WidgetToScreenOffset()); + LayoutDeviceIntPoint::ToUntyped(mPreLockPoint + aWidget->WidgetToScreenOffset())); // Don't retarget events to this element any more. nsIPresShell::SetCapturingContent(nullptr, CAPTURE_POINTERLOCK); diff --git a/dom/events/IMEContentObserver.cpp b/dom/events/IMEContentObserver.cpp index 836c6882abce..ac9de57b071e 100644 --- a/dom/events/IMEContentObserver.cpp +++ b/dom/events/IMEContentObserver.cpp @@ -449,15 +449,14 @@ IMEContentObserver::OnMouseButtonEvent(nsPresContext* aPresContext, nsIWidget* topLevelWidget = mWidget->GetTopLevelWidget(); if (topLevelWidget && topLevelWidget != mWidget) { charAtPt.mReply.mRect.MoveBy( - topLevelWidget->WidgetToScreenOffset() - - mWidget->WidgetToScreenOffset()); + topLevelWidget->WidgetToScreenOffsetUntyped() - + mWidget->WidgetToScreenOffsetUntyped()); } // The refPt is relative to its widget. // We should notify it with offset in the widget. if (aMouseEvent->widget != mWidget) { - charAtPt.refPoint += LayoutDeviceIntPoint::FromUntyped( - aMouseEvent->widget->WidgetToScreenOffset() - - mWidget->WidgetToScreenOffset()); + charAtPt.refPoint += aMouseEvent->widget->WidgetToScreenOffset() - + mWidget->WidgetToScreenOffset(); } IMENotification notification(NOTIFY_IME_OF_MOUSE_BUTTON_EVENT); diff --git a/dom/events/UIEvent.h b/dom/events/UIEvent.h index d13dc7880199..81b6097286b8 100644 --- a/dom/events/UIEvent.h +++ b/dom/events/UIEvent.h @@ -57,8 +57,7 @@ public: return LayoutDeviceIntPoint::ToUntyped(aEvent->refPoint); } - LayoutDeviceIntPoint offset = aEvent->refPoint + - LayoutDeviceIntPoint::FromUntyped(event->widget->WidgetToScreenOffset()); + LayoutDeviceIntPoint offset = aEvent->refPoint + event->widget->WidgetToScreenOffset(); nscoord factor = aPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom(); return nsIntPoint(nsPresContext::AppUnitsToIntCSSPixels(offset.x * factor), diff --git a/dom/events/WheelHandlingHelper.cpp b/dom/events/WheelHandlingHelper.cpp index ba586cfc3684..35441dd930a9 100644 --- a/dom/events/WheelHandlingHelper.cpp +++ b/dom/events/WheelHandlingHelper.cpp @@ -293,8 +293,8 @@ WheelTransaction::GetScreenPoint(WidgetGUIEvent* aEvent) { NS_ASSERTION(aEvent, "aEvent is null"); NS_ASSERTION(aEvent->widget, "aEvent-widget is null"); - return LayoutDeviceIntPoint::ToUntyped(aEvent->refPoint) + - aEvent->widget->WidgetToScreenOffset(); + return LayoutDeviceIntPoint::ToUntyped(aEvent->refPoint + + aEvent->widget->WidgetToScreenOffset()); } /* static */ uint32_t diff --git a/dom/plugins/base/nsPluginInstanceOwner.cpp b/dom/plugins/base/nsPluginInstanceOwner.cpp index 388af25cf89c..340d985f6648 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.cpp +++ b/dom/plugins/base/nsPluginInstanceOwner.cpp @@ -2116,8 +2116,7 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent) // Get reference point relative to screen: LayoutDeviceIntPoint rootPoint(-1, -1); if (widget) - rootPoint = anEvent.refPoint + - LayoutDeviceIntPoint::FromUntyped(widget->WidgetToScreenOffset()); + rootPoint = anEvent.refPoint + widget->WidgetToScreenOffset(); #ifdef MOZ_WIDGET_GTK Window root = GDK_ROOT_WINDOW(); #elif defined(MOZ_WIDGET_QT) diff --git a/embedding/browser/nsDocShellTreeOwner.cpp b/embedding/browser/nsDocShellTreeOwner.cpp index e4490a61e9ee..4787a2c2408a 100644 --- a/embedding/browser/nsDocShellTreeOwner.cpp +++ b/embedding/browser/nsDocShellTreeOwner.cpp @@ -1452,7 +1452,7 @@ ChromeTooltipListener::sTooltipCallback(nsITimer *aTimer, if (textFound) { nsString tipText(tooltipText); - nsIntPoint screenDot = widget->WidgetToScreenOffset(); + LayoutDeviceIntPoint screenDot = widget->WidgetToScreenOffset(); self->ShowTooltip(self->mMouseScreenX - screenDot.x, self->mMouseScreenY - screenDot.y, tipText); diff --git a/gfx/tests/gtest/TestCompositor.cpp b/gfx/tests/gtest/TestCompositor.cpp index cf0b9bf3664f..a8cf3c2674b9 100644 --- a/gfx/tests/gtest/TestCompositor.cpp +++ b/gfx/tests/gtest/TestCompositor.cpp @@ -71,7 +71,7 @@ public: virtual nsresult ConfigureChildren(const nsTArray& aConfigurations) MOZ_OVERRIDE { return NS_OK; } NS_IMETHOD Invalidate(const nsIntRect &aRect) MOZ_OVERRIDE { return NS_OK; } NS_IMETHOD SetTitle(const nsAString& title) MOZ_OVERRIDE { return NS_OK; } - virtual nsIntPoint WidgetToScreenOffset() MOZ_OVERRIDE { return nsIntPoint(0, 0); } + virtual LayoutDeviceIntPoint WidgetToScreenOffset() MOZ_OVERRIDE { return LayoutDeviceIntPoint(0, 0); } NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent, nsEventStatus& aStatus) MOZ_OVERRIDE { return NS_OK; } NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, bool aDoCapture) MOZ_OVERRIDE { return NS_OK; } diff --git a/layout/base/PositionedEventTargeting.cpp b/layout/base/PositionedEventTargeting.cpp index 99c26818c864..21c87473ab74 100644 --- a/layout/base/PositionedEventTargeting.cpp +++ b/layout/base/PositionedEventTargeting.cpp @@ -473,11 +473,11 @@ FindFrameTargetedByInputEvent(WidgetGUIEvent* aEvent, if (!view) { return target; } - nsIntPoint widgetPoint = nsLayoutUtils::TranslateViewToWidget( + LayoutDeviceIntPoint widgetPoint = nsLayoutUtils::TranslateViewToWidget( aRootFrame->PresContext(), view, point, aEvent->widget); if (widgetPoint.x != NS_UNCONSTRAINEDSIZE) { // If that succeeded, we update the point in the event - aEvent->refPoint = LayoutDeviceIntPoint::FromUntyped(widgetPoint); + aEvent->refPoint = widgetPoint; } return target; } diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index b1beb142d528..6da06c3d4a0c 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -2627,8 +2627,8 @@ nsLayoutUtils::TransformFrameRectToAncestor(nsIFrame* aFrame, NSFloatPixelsToAppUnits(float(result.height), destAppUnitsPerDevPixel)); } -static nsIntPoint GetWidgetOffset(nsIWidget* aWidget, nsIWidget*& aRootWidget) { - nsIntPoint offset(0, 0); +static LayoutDeviceIntPoint GetWidgetOffset(nsIWidget* aWidget, nsIWidget*& aRootWidget) { + LayoutDeviceIntPoint offset(0, 0); while ((aWidget->WindowType() == eWindowType_child || aWidget->IsPlugin())) { nsIWidget* parent = aWidget->GetParent(); @@ -2637,18 +2637,19 @@ static nsIntPoint GetWidgetOffset(nsIWidget* aWidget, nsIWidget*& aRootWidget) { } nsIntRect bounds; aWidget->GetBounds(bounds); - offset += bounds.TopLeft(); + offset += LayoutDeviceIntPoint::FromUntyped(bounds.TopLeft()); aWidget = parent; } aRootWidget = aWidget; return offset; } -static nsIntPoint WidgetToWidgetOffset(nsIWidget* aFrom, nsIWidget* aTo) { +static LayoutDeviceIntPoint +WidgetToWidgetOffset(nsIWidget* aFrom, nsIWidget* aTo) { nsIWidget* fromRoot; - nsIntPoint fromOffset = GetWidgetOffset(aFrom, fromRoot); + LayoutDeviceIntPoint fromOffset = GetWidgetOffset(aFrom, fromRoot); nsIWidget* toRoot; - nsIntPoint toOffset = GetWidgetOffset(aTo, toRoot); + LayoutDeviceIntPoint toOffset = GetWidgetOffset(aTo, toRoot); if (fromRoot == toRoot) { return fromOffset - toOffset; @@ -2667,14 +2668,13 @@ nsLayoutUtils::TranslateWidgetToView(nsPresContext* aPresContext, return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); } - LayoutDeviceIntPoint widgetPoint = aPt + - LayoutDeviceIntPoint::FromUntyped(WidgetToWidgetOffset(aWidget, viewWidget)); + LayoutDeviceIntPoint widgetPoint = aPt + WidgetToWidgetOffset(aWidget, viewWidget); nsPoint widgetAppUnits(aPresContext->DevPixelsToAppUnits(widgetPoint.x), aPresContext->DevPixelsToAppUnits(widgetPoint.y)); return widgetAppUnits - viewOffset; } -nsIntPoint +LayoutDeviceIntPoint nsLayoutUtils::TranslateViewToWidget(nsPresContext* aPresContext, nsView* aView, nsPoint aPt, nsIWidget* aWidget) @@ -2682,11 +2682,11 @@ nsLayoutUtils::TranslateViewToWidget(nsPresContext* aPresContext, nsPoint viewOffset; nsIWidget* viewWidget = aView->GetNearestWidget(&viewOffset); if (!viewWidget) { - return nsIntPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); + return LayoutDeviceIntPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); } - nsIntPoint relativeToViewWidget(aPresContext->AppUnitsToDevPixels(aPt.x + viewOffset.x), - aPresContext->AppUnitsToDevPixels(aPt.y + viewOffset.y)); + LayoutDeviceIntPoint relativeToViewWidget(aPresContext->AppUnitsToDevPixels(aPt.x + viewOffset.x), + aPresContext->AppUnitsToDevPixels(aPt.y + viewOffset.y)); return relativeToViewWidget + WidgetToWidgetOffset(viewWidget, aWidget); } diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index 6e67309c3fc6..5a8b0540e1b3 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -728,9 +728,10 @@ public: * @param aWidget the widget to which returned coordinates are relative * @return the point in the view's coordinates */ - static nsIntPoint TranslateViewToWidget(nsPresContext* aPresContext, - nsView* aView, nsPoint aPt, - nsIWidget* aWidget); + static mozilla::LayoutDeviceIntPoint + TranslateViewToWidget(nsPresContext* aPresContext, + nsView* aView, nsPoint aPt, + nsIWidget* aWidget); enum FrameForPointFlags { /** diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 78d299df0694..4f1c7bd62a80 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -8474,9 +8474,9 @@ PresShell::AdjustContextMenuKeyEvent(WidgetMouseEvent* aEvent) nsCOMPtr widget = popupFrame->GetNearestWidget(); aEvent->widget = widget; - nsIntPoint widgetPoint = widget->WidgetToScreenOffset(); + LayoutDeviceIntPoint widgetPoint = widget->WidgetToScreenOffset(); aEvent->refPoint = LayoutDeviceIntPoint::FromUntyped( - itemFrame->GetScreenRect().BottomLeft() - widgetPoint); + itemFrame->GetScreenRect().BottomLeft()) - widgetPoint; mCurrentEventContent = itemFrame->GetContent(); mCurrentEventFrame = itemFrame; diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 1d3d38c3c7d5..37656030c33e 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -4815,7 +4815,7 @@ nsRect nsIFrame::GetScreenRectInAppUnits() const nsCOMPtr rootWidget; presContext->PresShell()->GetViewManager()->GetRootWidget(getter_AddRefs(rootWidget)); if (rootWidget) { - nsIntPoint rootDevPx = rootWidget->WidgetToScreenOffset(); + LayoutDeviceIntPoint rootDevPx = rootWidget->WidgetToScreenOffset(); rootScreenPos.x = presContext->DevPixelsToAppUnits(rootDevPx.x); rootScreenPos.y = presContext->DevPixelsToAppUnits(rootDevPx.y); } diff --git a/layout/xul/nsResizerFrame.cpp b/layout/xul/nsResizerFrame.cpp index 228fbd77ae09..afdab2b22911 100644 --- a/layout/xul/nsResizerFrame.cpp +++ b/layout/xul/nsResizerFrame.cpp @@ -117,8 +117,7 @@ nsResizerFrame::HandleEvent(nsPresContext* aPresContext, LayoutDeviceIntPoint refPoint; if (!GetEventPoint(aEvent, refPoint)) return NS_OK; - mMouseDownPoint = refPoint + - LayoutDeviceIntPoint::FromUntyped(aEvent->widget->WidgetToScreenOffset()); + mMouseDownPoint = refPoint + aEvent->widget->WidgetToScreenOffset(); // we're tracking mTrackingMouseMove = true; @@ -166,8 +165,7 @@ nsResizerFrame::HandleEvent(nsPresContext* aPresContext, LayoutDeviceIntPoint refPoint; if (!GetEventPoint(aEvent, refPoint)) return NS_OK; - LayoutDeviceIntPoint screenPoint = refPoint + - LayoutDeviceIntPoint::FromUntyped(aEvent->widget->WidgetToScreenOffset()); + LayoutDeviceIntPoint screenPoint = refPoint + aEvent->widget->WidgetToScreenOffset(); LayoutDeviceIntPoint mouseMove(screenPoint - mMouseDownPoint); // Determine which direction to resize by checking the dir attribute. diff --git a/layout/xul/nsXULPopupManager.cpp b/layout/xul/nsXULPopupManager.cpp index d11f665d32e1..b55ccdc11eb0 100644 --- a/layout/xul/nsXULPopupManager.cpp +++ b/layout/xul/nsXULPopupManager.cpp @@ -746,7 +746,7 @@ nsXULPopupManager::ShowTooltipAtScreen(nsIContent* aPopup, if (rootPresContext) { nsIWidget *rootWidget = rootPresContext->GetRootWidget(); if (rootWidget) { - mCachedMousePoint -= rootWidget->WidgetToScreenOffset(); + mCachedMousePoint -= rootWidget->WidgetToScreenOffsetUntyped(); } } diff --git a/view/nsView.cpp b/view/nsView.cpp index 7ca917cb8a6e..63b0e4ba46ec 100644 --- a/view/nsView.cpp +++ b/view/nsView.cpp @@ -220,7 +220,7 @@ nsIntRect nsView::CalcWidgetBounds(nsWindowType aType) if (parentWidget && aType == eWindowType_popup && IsEffectivelyVisible()) { // put offset into screen coordinates. (based on client area origin) - nsIntPoint screenPoint = parentWidget->WidgetToScreenOffset(); + LayoutDeviceIntPoint screenPoint = parentWidget->WidgetToScreenOffset(); viewBounds += nsPoint(NSIntPixelsToAppUnits(screenPoint.x, p2a), NSIntPixelsToAppUnits(screenPoint.y, p2a)); } diff --git a/widget/PuppetWidget.h b/widget/PuppetWidget.h index d9c5dd6d00bf..95f9b77083f5 100644 --- a/widget/PuppetWidget.h +++ b/widget/PuppetWidget.h @@ -126,8 +126,8 @@ public: { return NS_ERROR_UNEXPECTED; } // PuppetWidgets are always at <0, 0>. - virtual nsIntPoint WidgetToScreenOffset() MOZ_OVERRIDE - { return nsIntPoint(0, 0); } + virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset() MOZ_OVERRIDE + { return mozilla::LayoutDeviceIntPoint(0, 0); } void InitEvent(WidgetGUIEvent& aEvent, nsIntPoint* aPoint = nullptr); diff --git a/widget/android/AndroidJavaWrappers.cpp b/widget/android/AndroidJavaWrappers.cpp index a3aefec79b24..27e9ffed4d75 100644 --- a/widget/android/AndroidJavaWrappers.cpp +++ b/widget/android/AndroidJavaWrappers.cpp @@ -730,7 +730,7 @@ AndroidGeckoEvent::MakeTouchEvent(nsIWidget* widget) event.modifiers = DOMModifiers(); event.time = Time(); - const nsIntPoint& offset = widget->WidgetToScreenOffset(); + const LayoutDeviceIntPoint& offset = widget->WidgetToScreenOffset(); event.touches.SetCapacity(endIndex - startIndex); for (int i = startIndex; i < endIndex; i++) { // In this code branch, we are dispatching this event directly @@ -796,7 +796,7 @@ AndroidGeckoEvent::MakeMultiTouchInput(nsIWidget* widget) return event; } - const nsIntPoint& offset = widget->WidgetToScreenOffset(); + const nsIntPoint& offset = widget->WidgetToScreenOffsetUntyped(); event.mTouches.SetCapacity(endIndex - startIndex); for (int i = startIndex; i < endIndex; i++) { nsIntPoint point = Points()[i] - offset; @@ -853,11 +853,10 @@ AndroidGeckoEvent::MakeMouseEvent(nsIWidget* widget) // We are dispatching this event directly into Gecko (as opposed to going // through the AsyncPanZoomController), and the Points() array has points // in CSS pixels, which we need to convert to LayoutDevice pixels. - const nsIntPoint& offset = widget->WidgetToScreenOffset(); + const LayoutDeviceIntPoint& offset = widget->WidgetToScreenOffset(); CSSToLayoutDeviceScale scale = widget->GetDefaultScale(); event.refPoint = LayoutDeviceIntPoint((Points()[0].x * scale.scale) - offset.x, (Points()[0].y * scale.scale) - offset.y); - return event; } diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp index 6d7bf270c97d..84edc194d12a 100644 --- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -630,7 +630,7 @@ nsWindow::BringToFront() NS_IMETHODIMP nsWindow::GetScreenBounds(nsIntRect &aRect) { - nsIntPoint p = WidgetToScreenOffset(); + LayoutDeviceIntPoint p = WidgetToScreenOffset(); aRect.x = p.x; aRect.y = p.y; @@ -640,10 +640,10 @@ nsWindow::GetScreenBounds(nsIntRect &aRect) return NS_OK; } -nsIntPoint +LayoutDeviceIntPoint nsWindow::WidgetToScreenOffset() { - nsIntPoint p(0, 0); + LayoutDeviceIntPoint p(0, 0); nsWindow *w = this; while (w && !w->IsTopLevel()) { @@ -1041,8 +1041,7 @@ nsWindow::OnContextmenuEvent(AndroidGeckoEvent *ae) WidgetMouseEvent contextMenuEvent(true, NS_CONTEXTMENU, this, WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal); contextMenuEvent.refPoint = - LayoutDeviceIntPoint(RoundedToInt(pt * GetDefaultScale())) - - LayoutDeviceIntPoint::FromUntyped(WidgetToScreenOffset()); + RoundedToInt(pt * GetDefaultScale()) - WidgetToScreenOffset(); contextMenuEvent.ignoreRootScrollFrame = true; contextMenuEvent.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH; diff --git a/widget/android/nsWindow.h b/widget/android/nsWindow.h index 0c8f5d133804..e21edf050c15 100644 --- a/widget/android/nsWindow.h +++ b/widget/android/nsWindow.h @@ -100,7 +100,7 @@ public: NS_IMETHOD Invalidate(const nsIntRect &aRect); NS_IMETHOD SetFocus(bool aRaise = false); NS_IMETHOD GetScreenBounds(nsIntRect &aRect); - virtual nsIntPoint WidgetToScreenOffset(); + virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset(); NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent, nsEventStatus& aStatus); nsEventStatus DispatchEvent(mozilla::WidgetGUIEvent* aEvent); diff --git a/widget/cocoa/nsChildView.h b/widget/cocoa/nsChildView.h index 65aaef78f2ff..a1be2604df40 100644 --- a/widget/cocoa/nsChildView.h +++ b/widget/cocoa/nsChildView.h @@ -401,7 +401,7 @@ public: virtual void* GetNativeData(uint32_t aDataType) MOZ_OVERRIDE; virtual nsresult ConfigureChildren(const nsTArray& aConfigurations) MOZ_OVERRIDE; - virtual nsIntPoint WidgetToScreenOffset() MOZ_OVERRIDE; + virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset() MOZ_OVERRIDE; virtual bool ShowsResizeIndicator(nsIntRect* aResizerRect) MOZ_OVERRIDE; static bool ConvertStatus(nsEventStatus aStatus) diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm index 2bbf250b33e8..369eadd17ed3 100644 --- a/widget/cocoa/nsChildView.mm +++ b/widget/cocoa/nsChildView.mm @@ -923,7 +923,7 @@ NS_IMETHODIMP nsChildView::GetClientBounds(nsIntRect &aRect) if (!mParentWidget) { // For top level widgets we want the position on screen, not the position // of this view inside the window. - aRect.MoveTo(WidgetToScreenOffset()); + aRect.MoveTo(WidgetToScreenOffsetUntyped()); } return NS_OK; } @@ -931,7 +931,7 @@ NS_IMETHODIMP nsChildView::GetClientBounds(nsIntRect &aRect) NS_IMETHODIMP nsChildView::GetScreenBounds(nsIntRect &aRect) { GetBounds(aRect); - aRect.MoveTo(WidgetToScreenOffset()); + aRect.MoveTo(WidgetToScreenOffsetUntyped()); return NS_OK; } @@ -1482,7 +1482,7 @@ void nsChildView::ReportSizeEvent() // Return the offset between this child view and the screen. // @return -- widget origin in device-pixel coords -nsIntPoint nsChildView::WidgetToScreenOffset() +LayoutDeviceIntPoint nsChildView::WidgetToScreenOffset() { NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN; @@ -1500,9 +1500,9 @@ nsIntPoint nsChildView::WidgetToScreenOffset() FlipCocoaScreenCoordinate(origin); // convert to device pixels - return CocoaPointsToDevPixels(origin); + return LayoutDeviceIntPoint::FromUntyped(CocoaPointsToDevPixels(origin)); - NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(nsIntPoint(0,0)); + NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(LayoutDeviceIntPoint(0,0)); } NS_IMETHODIMP nsChildView::CaptureRollupEvents(nsIRollupListener * aListener, diff --git a/widget/cocoa/nsCocoaWindow.h b/widget/cocoa/nsCocoaWindow.h index 814cd73b0198..530f05c4a58d 100644 --- a/widget/cocoa/nsCocoaWindow.h +++ b/widget/cocoa/nsCocoaWindow.h @@ -260,7 +260,7 @@ public: NS_IMETHOD SetModal(bool aState) MOZ_OVERRIDE; virtual bool IsVisible() const MOZ_OVERRIDE; NS_IMETHOD SetFocus(bool aState=false) MOZ_OVERRIDE; - virtual nsIntPoint WidgetToScreenOffset() MOZ_OVERRIDE; + virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset() MOZ_OVERRIDE; virtual nsIntPoint GetClientOffset() MOZ_OVERRIDE; virtual nsIntSize ClientToWindowSize(const nsIntSize& aClientSize) MOZ_OVERRIDE; diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm index e4a87bc15fdd..1dc2a788064b 100644 --- a/widget/cocoa/nsCocoaWindow.mm +++ b/widget/cocoa/nsCocoaWindow.mm @@ -1812,7 +1812,7 @@ NS_IMETHODIMP nsCocoaWindow::SetFocus(bool aState) return NS_OK; } -nsIntPoint nsCocoaWindow::WidgetToScreenOffset() +LayoutDeviceIntPoint nsCocoaWindow::WidgetToScreenOffset() { NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN; @@ -1823,9 +1823,9 @@ nsIntPoint nsCocoaWindow::WidgetToScreenOffset() } r = nsCocoaUtils::CocoaRectToGeckoRectDevPix(rect, BackingScaleFactor()); - return r.TopLeft(); + return LayoutDeviceIntPoint::FromUntyped(r.TopLeft()); - NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(nsIntPoint(0,0)); + NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(LayoutDeviceIntPoint(0,0)); } nsIntPoint nsCocoaWindow::GetClientOffset() diff --git a/widget/gonk/nsWindow.cpp b/widget/gonk/nsWindow.cpp index 4977500e2fdd..fd41496b8928 100644 --- a/widget/gonk/nsWindow.cpp +++ b/widget/gonk/nsWindow.cpp @@ -505,10 +505,10 @@ nsWindow::Invalidate(const nsIntRect &aRect) return NS_OK; } -nsIntPoint +LayoutDeviceIntPoint nsWindow::WidgetToScreenOffset() { - nsIntPoint p(0, 0); + LayoutDeviceIntPoint p(0, 0); nsWindow *w = this; while (w && w->mParent) { diff --git a/widget/gonk/nsWindow.h b/widget/gonk/nsWindow.h index cf5d140c4ad9..925623a72d6b 100644 --- a/widget/gonk/nsWindow.h +++ b/widget/gonk/nsWindow.h @@ -86,7 +86,7 @@ public: { return NS_OK; } - virtual nsIntPoint WidgetToScreenOffset(); + virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset(); void DispatchTouchInputViaAPZ(mozilla::MultiTouchInput& aInput); NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent, nsEventStatus& aStatus); diff --git a/widget/gtk/nsDragService.cpp b/widget/gtk/nsDragService.cpp index 3fe0abb39bf6..cc16157ea81c 100644 --- a/widget/gtk/nsDragService.cpp +++ b/widget/gtk/nsDragService.cpp @@ -1755,7 +1755,7 @@ nsDragService::ScheduleDropEvent(nsWindow *aWindow, return FALSE; } - SetDragEndPoint(aWindowPoint + aWindow->WidgetToScreenOffset()); + SetDragEndPoint(aWindowPoint + aWindow->WidgetToScreenOffsetUntyped()); // We'll reply with gtk_drag_finish(). return TRUE; diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index cf945b0765d0..f37863dd864d 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -1473,10 +1473,10 @@ nsWindow::GetScreenBounds(nsIntRect &aRect) // use the point including window decorations gint x, y; gdk_window_get_root_origin(gtk_widget_get_window(GTK_WIDGET(mContainer)), &x, &y); - aRect.MoveTo(GdkPointToDevicePixels({ x, y })); + aRect.MoveTo(LayoutDevicePixel::ToUntyped(GdkPointToDevicePixels({ x, y }))); } else { - aRect.MoveTo(WidgetToScreenOffset()); + aRect.MoveTo(WidgetToScreenOffsetUntyped()); } // mBounds.Size() is the window bounds, not the window-manager frame // bounds (bug 581863). gdk_window_get_frame_extents would give the @@ -1797,7 +1797,7 @@ nsWindow::SetIcon(const nsAString& aIconSpec) } -nsIntPoint +LayoutDeviceIntPoint nsWindow::WidgetToScreenOffset() { gint x = 0, y = 0; @@ -2617,8 +2617,7 @@ nsWindow::OnMotionNotifyEvent(GdkEventMotion *aEvent) } else { LayoutDeviceIntPoint point(NSToIntFloor(aEvent->x_root), NSToIntFloor(aEvent->y_root)); - event.refPoint = point - - LayoutDeviceIntPoint::FromUntyped(WidgetToScreenOffset()); + event.refPoint = point - WidgetToScreenOffset(); } modifierState = aEvent->state; @@ -2696,8 +2695,7 @@ nsWindow::InitButtonEvent(WidgetMouseEvent& aEvent, } else { LayoutDeviceIntPoint point(NSToIntFloor(aGdkEvent->x_root), NSToIntFloor(aGdkEvent->y_root)); - aEvent.refPoint = point - - LayoutDeviceIntPoint::FromUntyped(WidgetToScreenOffset()); + aEvent.refPoint = point - WidgetToScreenOffset(); } guint modifierState = aGdkEvent->state; @@ -3209,8 +3207,7 @@ nsWindow::OnScrollEvent(GdkEventScroll *aEvent) // coordinates relative to this widget. LayoutDeviceIntPoint point(NSToIntFloor(aEvent->x_root), NSToIntFloor(aEvent->y_root)); - wheelEvent.refPoint = point - - LayoutDeviceIntPoint::FromUntyped(WidgetToScreenOffset()); + wheelEvent.refPoint = point - WidgetToScreenOffset(); } KeymapWrapper::InitInputEvent(wheelEvent, aEvent->state); @@ -6338,7 +6335,7 @@ nsWindow::GetDragInfo(WidgetMouseEvent* aMouseEvent, // moved since the mousedown. (On the other hand, it's quite likely // that the mouse has moved, which is why we use the mouse position // from the event.) - nsIntPoint offset = aMouseEvent->widget->WidgetToScreenOffset(); + LayoutDeviceIntPoint offset = aMouseEvent->widget->WidgetToScreenOffset(); *aRootX = aMouseEvent->refPoint.x + offset.x; *aRootY = aMouseEvent->refPoint.y + offset.y; @@ -6499,11 +6496,11 @@ nsWindow::GdkCoordToDevicePixels(gint coord) { return coord * GdkScaleFactor(); } -nsIntPoint +LayoutDeviceIntPoint nsWindow::GdkPointToDevicePixels(GdkPoint point) { gint scale = GdkScaleFactor(); - return nsIntPoint(point.x * scale, - point.y * scale); + return LayoutDeviceIntPoint(point.x * scale, + point.y * scale); } nsIntRect diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h index f86650366278..a0d6d5487d84 100644 --- a/widget/gtk/nsWindow.h +++ b/widget/gtk/nsWindow.h @@ -138,7 +138,7 @@ public: NS_IMETHOD SetTitle(const nsAString& aTitle) MOZ_OVERRIDE; NS_IMETHOD SetIcon(const nsAString& aIconSpec) MOZ_OVERRIDE; NS_IMETHOD SetWindowClass(const nsAString& xulWinType) MOZ_OVERRIDE; - virtual nsIntPoint WidgetToScreenOffset() MOZ_OVERRIDE; + virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset() MOZ_OVERRIDE; NS_IMETHOD EnableDragDrop(bool aEnable) MOZ_OVERRIDE; NS_IMETHOD CaptureMouse(bool aCapture) MOZ_OVERRIDE; NS_IMETHOD CaptureRollupEvents(nsIRollupListener *aListener, @@ -498,7 +498,7 @@ private: // From GDK int GdkCoordToDevicePixels(gint coord); - nsIntPoint GdkPointToDevicePixels(GdkPoint point); + mozilla::LayoutDeviceIntPoint GdkPointToDevicePixels(GdkPoint point); nsIntRect GdkRectToDevicePixels(GdkRectangle rect); }; diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h index ee76fed042fa..2983a6158bb9 100644 --- a/widget/nsIWidget.h +++ b/widget/nsIWidget.h @@ -1668,12 +1668,16 @@ class nsIWidget : public nsISupports { NS_IMETHOD SetIcon(const nsAString& anIconSpec) = 0; /** - * Return this widget's origin in screen coordinates. + * Return this widget's origin in screen coordinates. The untyped version + * exists temporarily to ease conversion to typed coordinates. * * @return screen coordinates stored in the x,y members */ - virtual nsIntPoint WidgetToScreenOffset() = 0; + virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset() = 0; + virtual nsIntPoint WidgetToScreenOffsetUntyped() { + return mozilla::LayoutDeviceIntPoint::ToUntyped(WidgetToScreenOffset()); + } /** * Given the specified client size, return the corresponding window size, diff --git a/widget/qt/nsWindow.cpp b/widget/qt/nsWindow.cpp index 193d39e22bef..680356b530b0 100644 --- a/widget/qt/nsWindow.cpp +++ b/widget/qt/nsWindow.cpp @@ -626,7 +626,7 @@ nsWindow::Invalidate(const nsIntRect &aRect) return NS_OK; } -nsIntPoint +LayoutDeviceIntPoint nsWindow::WidgetToScreenOffset() { NS_ENSURE_TRUE(mWidget, nsIntPoint(0,0)); @@ -634,7 +634,7 @@ nsWindow::WidgetToScreenOffset() QPoint origin(0, 0); origin = mWidget->mapToGlobal(origin); - return nsIntPoint(origin.x(), origin.y()); + return LayoutDeviceIntPoint(origin.x(), origin.y()); } void* diff --git a/widget/qt/nsWindow.h b/widget/qt/nsWindow.h index 70db05e60870..bf970a091205 100644 --- a/widget/qt/nsWindow.h +++ b/widget/qt/nsWindow.h @@ -124,7 +124,7 @@ public: { return NS_OK; } - virtual nsIntPoint WidgetToScreenOffset(); + virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset(); NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent, nsEventStatus& aStatus); NS_IMETHOD CaptureRollupEvents(nsIRollupListener *aListener, diff --git a/widget/windows/nsIMM32Handler.cpp b/widget/windows/nsIMM32Handler.cpp index e5a922d0fbb6..7eb9bd321e5e 100644 --- a/widget/windows/nsIMM32Handler.cpp +++ b/widget/windows/nsIMM32Handler.cpp @@ -1957,7 +1957,7 @@ nsIMM32Handler::SetIMERelatedWindowsPosOnPlugin(nsWindow* aWindow, // window needs to be specified the position in the client area. nsWindow* toplevelWindow = aWindow->GetTopLevelWindow(false); nsIntRect pluginRectInScreen = - editorRectEvent.mReply.mRect + toplevelWindow->WidgetToScreenOffset(); + editorRectEvent.mReply.mRect + toplevelWindow->WidgetToScreenOffsetUntyped(); nsIntRect winRectInScreen; aWindow->GetClientBounds(winRectInScreen); // composition window cannot be positioned on the edge of client area. @@ -1974,7 +1974,7 @@ nsIMM32Handler::SetIMERelatedWindowsPosOnPlugin(nsWindow* aWindow, int32_t yMost = std::min(pluginRectInScreen.YMost(), winRectInScreen.YMost()); clippedPluginRect.width = std::max(0, xMost - clippedPluginRect.x); clippedPluginRect.height = std::max(0, yMost - clippedPluginRect.y); - clippedPluginRect -= aWindow->WidgetToScreenOffset(); + clippedPluginRect -= aWindow->WidgetToScreenOffsetUntyped(); // Cover the plugin with native caret. This prevents IME's window and plugin // overlap. @@ -2013,10 +2013,10 @@ nsIMM32Handler::ResolveIMECaretPos(nsIWidget* aReferenceWidget, return; if (aReferenceWidget) - aOutRect.MoveBy(aReferenceWidget->WidgetToScreenOffset()); + aOutRect.MoveBy(aReferenceWidget->WidgetToScreenOffsetUntyped()); if (aNewOriginWidget) - aOutRect.MoveBy(-aNewOriginWidget->WidgetToScreenOffset()); + aOutRect.MoveBy(-aNewOriginWidget->WidgetToScreenOffsetUntyped()); } /* static */ nsresult diff --git a/widget/windows/nsTextStore.cpp b/widget/windows/nsTextStore.cpp index 8156c4248d47..ae7d53a8b0fb 100644 --- a/widget/windows/nsTextStore.cpp +++ b/widget/windows/nsTextStore.cpp @@ -3198,7 +3198,7 @@ nsTextStore::GetTextExt(TsViewCookie vcView, return E_FAIL; } - event.mReply.mRect.MoveBy(refWindow->WidgetToScreenOffset()); + event.mReply.mRect.MoveBy(refWindow->WidgetToScreenOffsetUntyped()); } // get bounding screen rect to test for clipping @@ -3336,7 +3336,7 @@ nsTextStore::GetScreenExtInternal(RECT &aScreenExt) // Clip frame rect to window rect boundRect.IntersectRect(event.mReply.mRect, boundRect); if (!boundRect.IsEmpty()) { - boundRect.MoveBy(refWindow->WidgetToScreenOffset()); + boundRect.MoveBy(refWindow->WidgetToScreenOffsetUntyped()); ::SetRect(&aScreenExt, boundRect.x, boundRect.y, boundRect.XMost(), boundRect.YMost()); } else { @@ -4325,8 +4325,8 @@ nsTextStore::CreateNativeCaret() } if (toplevelWindow != window) { - caretRect.MoveBy(toplevelWindow->WidgetToScreenOffset()); - caretRect.MoveBy(-window->WidgetToScreenOffset()); + caretRect.MoveBy(toplevelWindow->WidgetToScreenOffsetUntyped()); + caretRect.MoveBy(-window->WidgetToScreenOffsetUntyped()); } ::SetCaretPos(caretRect.x, caretRect.y); diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index 5bd07ff155e4..46340afd430a 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -1991,7 +1991,7 @@ nsIntPoint nsWindow::GetClientOffset() RECT r1; GetWindowRect(mWnd, &r1); - nsIntPoint pt = WidgetToScreenOffset(); + LayoutDeviceIntPoint pt = WidgetToScreenOffset(); return nsIntPoint(pt.x - r1.left, pt.y - r1.top); } @@ -3061,13 +3061,13 @@ NS_METHOD nsWindow::SetIcon(const nsAString& aIconSpec) * **************************************************************/ -nsIntPoint nsWindow::WidgetToScreenOffset() +LayoutDeviceIntPoint nsWindow::WidgetToScreenOffset() { POINT point; point.x = 0; point.y = 0; ::ClientToScreen(mWnd, &point); - return nsIntPoint(point.x, point.y); + return LayoutDeviceIntPoint(point.x, point.y); } nsIntSize nsWindow::ClientToWindowSize(const nsIntSize& aClientSize) @@ -3819,7 +3819,7 @@ bool nsWindow::DispatchMouseEvent(uint32_t aEventType, WPARAM wParam, aInputSource == nsIDOMMouseEvent::MOZ_SOURCE_PEN || !(WinUtils::GetIsMouseFromTouch(aEventType) && mTouchWindow); - nsIntPoint mpScreen = eventPoint + WidgetToScreenOffset(); + nsIntPoint mpScreen = eventPoint + WidgetToScreenOffsetUntyped(); // Suppress mouse moves caused by widget creation if (aEventType == NS_MOUSE_MOVE) diff --git a/widget/windows/nsWindow.h b/widget/windows/nsWindow.h index e580254debe0..d76931dd8240 100644 --- a/widget/windows/nsWindow.h +++ b/widget/windows/nsWindow.h @@ -136,7 +136,7 @@ public: virtual void FreeNativeData(void * data, uint32_t aDataType); NS_IMETHOD SetTitle(const nsAString& aTitle); NS_IMETHOD SetIcon(const nsAString& aIconSpec); - virtual nsIntPoint WidgetToScreenOffset(); + virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset(); virtual nsIntSize ClientToWindowSize(const nsIntSize& aClientSize); NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent, nsEventStatus& aStatus); diff --git a/widget/windows/winrt/MetroWidget.cpp b/widget/windows/winrt/MetroWidget.cpp index 2c4ad6e06035..a194f1286632 100644 --- a/widget/windows/winrt/MetroWidget.cpp +++ b/widget/windows/winrt/MetroWidget.cpp @@ -1492,10 +1492,10 @@ MetroWidget::SetTitle(const nsAString& aTitle) return NS_OK; } -nsIntPoint +LayoutDeviceIntPoint MetroWidget::WidgetToScreenOffset() { - return nsIntPoint(0,0); + return LayoutDeviceIntPoint(0,0); } NS_IMETHODIMP diff --git a/widget/windows/winrt/MetroWidget.h b/widget/windows/winrt/MetroWidget.h index 74742d98705a..bd6c2d465663 100644 --- a/widget/windows/winrt/MetroWidget.h +++ b/widget/windows/winrt/MetroWidget.h @@ -172,7 +172,7 @@ public: virtual nsresult ConfigureChildren(const nsTArray& aConfigurations); virtual void* GetNativeData(uint32_t aDataType); virtual void FreeNativeData(void * data, uint32_t aDataType); - virtual nsIntPoint WidgetToScreenOffset(); + virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset(); already_AddRefed GetPresShell(); From ec6ce0074bdc654abdce1ae92ab19da238b0b09d Mon Sep 17 00:00:00 2001 From: David Zbarsky Date: Wed, 4 Feb 2015 15:21:03 -0500 Subject: [PATCH 03/74] Bug 1125040 - Use LayoutDeviceIntPoint in XULPopupManager r=botond --- layout/xul/nsXULPopupManager.cpp | 16 ++++++++-------- layout/xul/nsXULPopupManager.h | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/layout/xul/nsXULPopupManager.cpp b/layout/xul/nsXULPopupManager.cpp index b55ccdc11eb0..9be2c814bd97 100644 --- a/layout/xul/nsXULPopupManager.cpp +++ b/layout/xul/nsXULPopupManager.cpp @@ -537,7 +537,7 @@ void nsXULPopupManager::InitTriggerEvent(nsIDOMEvent* aEvent, nsIContent* aPopup, nsIContent** aTriggerContent) { - mCachedMousePoint = nsIntPoint(0, 0); + mCachedMousePoint = LayoutDeviceIntPoint(0, 0); if (aTriggerContent) { *aTriggerContent = nullptr; @@ -598,8 +598,8 @@ nsXULPopupManager::InitTriggerEvent(nsIDOMEvent* aEvent, nsIContent* aPopup, else if (rootDocumentRootFrame) { nsPoint pnt = nsLayoutUtils::GetEventCoordinatesRelativeTo(event, rootDocumentRootFrame); - mCachedMousePoint = nsIntPoint(rootDocPresContext->AppUnitsToDevPixels(pnt.x), - rootDocPresContext->AppUnitsToDevPixels(pnt.y)); + mCachedMousePoint = LayoutDeviceIntPoint(rootDocPresContext->AppUnitsToDevPixels(pnt.x), + rootDocPresContext->AppUnitsToDevPixels(pnt.y)); } } } @@ -738,15 +738,15 @@ nsXULPopupManager::ShowTooltipAtScreen(nsIContent* aPopup, InitTriggerEvent(nullptr, nullptr, nullptr); nsPresContext* pc = popupFrame->PresContext(); - mCachedMousePoint = nsIntPoint(pc->CSSPixelsToDevPixels(aXPos), - pc->CSSPixelsToDevPixels(aYPos)); + mCachedMousePoint = LayoutDeviceIntPoint(pc->CSSPixelsToDevPixels(aXPos), + pc->CSSPixelsToDevPixels(aYPos)); // coordinates are relative to the root widget nsPresContext* rootPresContext = pc->GetRootPresContext(); if (rootPresContext) { nsIWidget *rootWidget = rootPresContext->GetRootWidget(); if (rootWidget) { - mCachedMousePoint -= rootWidget->WidgetToScreenOffsetUntyped(); + mCachedMousePoint -= rootWidget->WidgetToScreenOffset(); } } @@ -1323,11 +1323,11 @@ nsXULPopupManager::FirePopupShowingEvent(nsIContent* aPopup, event.widget = nullptr; } - event.refPoint = LayoutDeviceIntPoint::FromUntyped(mCachedMousePoint); + event.refPoint = mCachedMousePoint; event.modifiers = mCachedModifiers; EventDispatcher::Dispatch(popup, presContext, &event, nullptr, &status); - mCachedMousePoint = nsIntPoint(0, 0); + mCachedMousePoint = LayoutDeviceIntPoint(0, 0); mOpeningPopup = nullptr; mCachedModifiers = 0; diff --git a/layout/xul/nsXULPopupManager.h b/layout/xul/nsXULPopupManager.h index 54583baceb57..8136e86ef9ce 100644 --- a/layout/xul/nsXULPopupManager.h +++ b/layout/xul/nsXULPopupManager.h @@ -743,7 +743,7 @@ protected: int32_t mRangeOffset; // Device pixels relative to the showing popup's presshell's // root prescontext's root frame. - nsIntPoint mCachedMousePoint; + mozilla::LayoutDeviceIntPoint mCachedMousePoint; // cached modifiers mozilla::Modifiers mCachedModifiers; From a49d65a4068de5474856ef2390702ea0d2d790e0 Mon Sep 17 00:00:00 2001 From: David Zbarsky Date: Wed, 4 Feb 2015 15:21:03 -0500 Subject: [PATCH 04/74] Bug 1125040 - Use LayoutDeviceIntPoint in nsTitleBarFrame r=botond --- layout/xul/nsTitleBarFrame.cpp | 4 ++-- layout/xul/nsTitleBarFrame.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/layout/xul/nsTitleBarFrame.cpp b/layout/xul/nsTitleBarFrame.cpp index b1835db9ccc3..fea19176e150 100644 --- a/layout/xul/nsTitleBarFrame.cpp +++ b/layout/xul/nsTitleBarFrame.cpp @@ -81,7 +81,7 @@ nsTitleBarFrame::HandleEvent(nsPresContext* aPresContext, nsIPresShell::SetCapturingContent(GetContent(), CAPTURE_IGNOREALLOWED); // remember current mouse coordinates. - mLastPoint = LayoutDeviceIntPoint::ToUntyped(aEvent->refPoint); + mLastPoint = aEvent->refPoint; } } @@ -110,7 +110,7 @@ nsTitleBarFrame::HandleEvent(nsPresContext* aPresContext, case NS_MOUSE_MOVE: { if(mTrackingMouseMove) { - nsIntPoint nsMoveBy = LayoutDeviceIntPoint::ToUntyped(aEvent->refPoint) - mLastPoint; + LayoutDeviceIntPoint nsMoveBy = aEvent->refPoint - mLastPoint; nsIFrame* parent = GetParent(); while (parent) { diff --git a/layout/xul/nsTitleBarFrame.h b/layout/xul/nsTitleBarFrame.h index f4e9881a92fb..2b9f6441bcb7 100644 --- a/layout/xul/nsTitleBarFrame.h +++ b/layout/xul/nsTitleBarFrame.h @@ -32,8 +32,8 @@ public: void UpdateMouseThrough() MOZ_OVERRIDE { AddStateBits(NS_FRAME_MOUSE_THROUGH_NEVER); } protected: - bool mTrackingMouseMove; - nsIntPoint mLastPoint; + bool mTrackingMouseMove; + mozilla::LayoutDeviceIntPoint mLastPoint; }; // class nsTitleBarFrame From 6382284e6c9d529385c2b98ff1b129e4384f7c8b Mon Sep 17 00:00:00 2001 From: David Zbarsky Date: Wed, 4 Feb 2015 15:21:03 -0500 Subject: [PATCH 05/74] Bug 1125040 - Use LayoutDeviceIntPoint in nsFramesetFrame r=botond --- layout/generic/nsFrameSetFrame.cpp | 2 +- layout/generic/nsFrameSetFrame.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/layout/generic/nsFrameSetFrame.cpp b/layout/generic/nsFrameSetFrame.cpp index 73df792316e2..d048dbdd050a 100644 --- a/layout/generic/nsFrameSetFrame.cpp +++ b/layout/generic/nsFrameSetFrame.cpp @@ -1296,7 +1296,7 @@ nsHTMLFramesetFrame::StartMouseDrag(nsPresContext* aPresContext, mDragger = aBorder; - mFirstDragPoint = LayoutDeviceIntPoint::ToUntyped(aEvent->refPoint); + mFirstDragPoint = aEvent->refPoint; // Store the original frame sizes if (mDragger->mVertical) { diff --git a/layout/generic/nsFrameSetFrame.h b/layout/generic/nsFrameSetFrame.h index 1da0dee41bf2..bee754ab53af 100644 --- a/layout/generic/nsFrameSetFrame.h +++ b/layout/generic/nsFrameSetFrame.h @@ -199,7 +199,7 @@ protected: nsBorderColor* mChildBorderColors; nscoord* mRowSizes; // currently computed row sizes nscoord* mColSizes; // currently computed col sizes - nsIntPoint mFirstDragPoint; + mozilla::LayoutDeviceIntPoint mFirstDragPoint; int32_t mNumRows; int32_t mNumCols; int32_t mNonBorderChildCount; From 77ae10e9d504f179c889387145d2414f2be163b0 Mon Sep 17 00:00:00 2001 From: David Zbarsky Date: Wed, 4 Feb 2015 15:21:03 -0500 Subject: [PATCH 06/74] Bug 1125040 - Use LayoutDeviceIntPoint in IME code r=botond --- dom/base/nsQueryContentEventResult.cpp | 2 +- dom/base/nsQueryContentEventResult.h | 4 ++-- dom/events/ContentEventHandler.cpp | 16 ++++++++-------- dom/events/IMEContentObserver.cpp | 7 ++++--- dom/ipc/PBrowser.ipdl | 13 +++++++------ dom/ipc/TabParent.cpp | 21 ++++++++++++--------- dom/ipc/TabParent.h | 18 +++++++++--------- widget/PuppetWidget.cpp | 18 +++++++++--------- widget/PuppetWidget.h | 6 +++--- widget/TextEvents.h | 2 +- widget/cocoa/TextInputHandler.mm | 5 +++-- widget/windows/nsIMM32Handler.cpp | 8 ++++---- widget/windows/nsTextStore.cpp | 10 +++++----- 13 files changed, 68 insertions(+), 62 deletions(-) diff --git a/dom/base/nsQueryContentEventResult.cpp b/dom/base/nsQueryContentEventResult.cpp index c451952a03f9..b1b6ba6607f9 100644 --- a/dom/base/nsQueryContentEventResult.cpp +++ b/dom/base/nsQueryContentEventResult.cpp @@ -149,5 +149,5 @@ nsQueryContentEventResult::SetEventResult(nsIWidget* aWidget, // Convert the top widget related coordinates to the given widget's. LayoutDeviceIntPoint offset = aWidget->WidgetToScreenOffset() - topWidget->WidgetToScreenOffset(); - mRect.MoveBy(-LayoutDeviceIntPoint::ToUntyped(offset)); + mRect.MoveBy(-offset); } diff --git a/dom/base/nsQueryContentEventResult.h b/dom/base/nsQueryContentEventResult.h index 1c6de847d255..8a3d86ec369a 100644 --- a/dom/base/nsQueryContentEventResult.h +++ b/dom/base/nsQueryContentEventResult.h @@ -31,10 +31,10 @@ protected: uint32_t mOffset; nsString mString; - nsIntRect mRect; + mozilla::LayoutDeviceIntRect mRect; bool mSucceeded; bool mReversed; }; -#endif // mozilla_dom_nsQueryContentEventResult_h \ No newline at end of file +#endif // mozilla_dom_nsQueryContentEventResult_h diff --git a/dom/events/ContentEventHandler.cpp b/dom/events/ContentEventHandler.cpp index 3c3665a50a93..f6f6f6734fad 100644 --- a/dom/events/ContentEventHandler.cpp +++ b/dom/events/ContentEventHandler.cpp @@ -182,8 +182,8 @@ ContentEventHandler::QueryContentRect(nsIContent* aContent, resultRect.UnionRect(resultRect, frameRect); } - aEvent->mReply.mRect = - resultRect.ToOutsidePixels(mPresContext->AppUnitsPerDevPixel()); + aEvent->mReply.mRect = LayoutDevicePixel::FromUntyped( + resultRect.ToOutsidePixels(mPresContext->AppUnitsPerDevPixel())); aEvent->mSucceeded = true; return NS_OK; @@ -992,8 +992,8 @@ ContentEventHandler::OnQueryTextRect(WidgetQueryContentEvent* aEvent) } else { rect.UnionRect(rect, frameRect); } - aEvent->mReply.mRect = - rect.ToOutsidePixels(mPresContext->AppUnitsPerDevPixel()); + aEvent->mReply.mRect = LayoutDevicePixel::FromUntyped( + rect.ToOutsidePixels(mPresContext->AppUnitsPerDevPixel())); aEvent->mSucceeded = true; return NS_OK; } @@ -1043,8 +1043,8 @@ ContentEventHandler::OnQueryCaretRect(WidgetQueryContentEvent* aEvent) } rv = ConvertToRootViewRelativeOffset(caretFrame, caretRect); NS_ENSURE_SUCCESS(rv, rv); - aEvent->mReply.mRect = - caretRect.ToOutsidePixels(caretFrame->PresContext()->AppUnitsPerDevPixel()); + aEvent->mReply.mRect = LayoutDevicePixel::FromUntyped( + caretRect.ToOutsidePixels(caretFrame->PresContext()->AppUnitsPerDevPixel())); aEvent->mReply.mOffset = aEvent->mInput.mOffset; aEvent->mSucceeded = true; return NS_OK; @@ -1076,8 +1076,8 @@ ContentEventHandler::OnQueryCaretRect(WidgetQueryContentEvent* aEvent) rv = ConvertToRootViewRelativeOffset(frame, rect); NS_ENSURE_SUCCESS(rv, rv); - aEvent->mReply.mRect = - rect.ToOutsidePixels(mPresContext->AppUnitsPerDevPixel()); + aEvent->mReply.mRect = LayoutDevicePixel::FromUntyped( + rect.ToOutsidePixels(mPresContext->AppUnitsPerDevPixel())); aEvent->mSucceeded = true; return NS_OK; } diff --git a/dom/events/IMEContentObserver.cpp b/dom/events/IMEContentObserver.cpp index ac9de57b071e..5519e1bf1163 100644 --- a/dom/events/IMEContentObserver.cpp +++ b/dom/events/IMEContentObserver.cpp @@ -449,8 +449,8 @@ IMEContentObserver::OnMouseButtonEvent(nsPresContext* aPresContext, nsIWidget* topLevelWidget = mWidget->GetTopLevelWidget(); if (topLevelWidget && topLevelWidget != mWidget) { charAtPt.mReply.mRect.MoveBy( - topLevelWidget->WidgetToScreenOffsetUntyped() - - mWidget->WidgetToScreenOffsetUntyped()); + topLevelWidget->WidgetToScreenOffset() - + mWidget->WidgetToScreenOffset()); } // The refPt is relative to its widget. // We should notify it with offset in the widget. @@ -464,7 +464,8 @@ IMEContentObserver::OnMouseButtonEvent(nsPresContext* aPresContext, notification.mMouseButtonEventData.mOffset = charAtPt.mReply.mOffset; notification.mMouseButtonEventData.mCursorPos.Set( LayoutDeviceIntPoint::ToUntyped(charAtPt.refPoint)); - notification.mMouseButtonEventData.mCharRect.Set(charAtPt.mReply.mRect); + notification.mMouseButtonEventData.mCharRect.Set( + LayoutDevicePixel::ToUntyped(charAtPt.mReply.mRect)); notification.mMouseButtonEventData.mButton = aMouseEvent->button; notification.mMouseButtonEventData.mButtons = aMouseEvent->buttons; notification.mMouseButtonEventData.mModifiers = aMouseEvent->modifiers; diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index 657464bfe260..ed10a436a606 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -25,6 +25,7 @@ using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h"; using class mozilla::gfx::Matrix from "mozilla/gfx/Matrix.h"; using struct gfxSize from "gfxPoint.h"; using CSSRect from "Units.h"; +using LayoutDeviceIntRect from "Units.h"; using struct mozilla::layers::FrameMetrics from "FrameMetrics.h"; using struct mozilla::layers::ScrollableLayerGuid from "FrameMetrics.h"; using struct mozilla::layers::ZoomConstraints from "FrameMetrics.h"; @@ -206,9 +207,9 @@ parent: * caretRect The rect of IME caret */ prio(urgent) async NotifyIMESelectedCompositionRect(uint32_t offset, - nsIntRect[] rect, + LayoutDeviceIntRect[] rect, uint32_t caretOffset, - nsIntRect caretRect); + LayoutDeviceIntRect caretRect); /** * Notifies chrome that there has been a change in selection @@ -245,7 +246,7 @@ parent: * * rect Rect of current focused editor */ - prio(urgent) async NotifyIMEEditorRect(nsIntRect rect); + prio(urgent) async NotifyIMEEditorRect(LayoutDeviceIntRect rect); /** * Notifies chrome to position change @@ -253,9 +254,9 @@ parent: * editorRect Rect of current focused editor * compositionRects Rects of current composition string */ - prio(urgent) async NotifyIMEPositionChange(nsIntRect editorRect, - nsIntRect[] compositionRects, - nsIntRect caretRect); + prio(urgent) async NotifyIMEPositionChange(LayoutDeviceIntRect editorRect, + LayoutDeviceIntRect[] compositionRects, + LayoutDeviceIntRect caretRect); /** * Instructs chrome to end any pending composition diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index 4ecc6e7bdf41..ce71264c4b94 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -1612,9 +1612,9 @@ TabParent::RecvNotifyIMETextChange(const uint32_t& aStart, bool TabParent::RecvNotifyIMESelectedCompositionRect( const uint32_t& aOffset, - InfallibleTArray&& aRects, + InfallibleTArray&& aRects, const uint32_t& aCaretOffset, - const nsIntRect& aCaretRect) + const LayoutDeviceIntRect& aCaretRect) { // add rect to cache for another query mIMECompositionRectOffset = aOffset; @@ -1684,7 +1684,7 @@ TabParent::RecvNotifyIMEMouseButtonEvent( } bool -TabParent::RecvNotifyIMEEditorRect(const nsIntRect& aRect) +TabParent::RecvNotifyIMEEditorRect(const LayoutDeviceIntRect& aRect) { mIMEEditorRect = aRect; return true; @@ -1692,9 +1692,9 @@ TabParent::RecvNotifyIMEEditorRect(const nsIntRect& aRect) bool TabParent::RecvNotifyIMEPositionChange( - const nsIntRect& aEditorRect, - InfallibleTArray&& aCompositionRects, - const nsIntRect& aCaretRect) + const LayoutDeviceIntRect& aEditorRect, + InfallibleTArray&& aCompositionRects, + const LayoutDeviceIntRect& aCaretRect) { mIMEEditorRect = aEditorRect; mIMECompositionRects = aCompositionRects; @@ -1929,7 +1929,8 @@ TabParent::HandleQueryContentEvent(WidgetQueryContentEvent& aEvent) aEvent.mReply.mRect.Union(mIMECompositionRects[i]); } aEvent.mReply.mOffset = aEvent.mInput.mOffset; - aEvent.mReply.mRect = aEvent.mReply.mRect - GetChildProcessOffset(); + aEvent.mReply.mRect = + aEvent.mReply.mRect - LayoutDevicePixel::FromUntyped(GetChildProcessOffset()); aEvent.mSucceeded = true; } break; @@ -1940,13 +1941,15 @@ TabParent::HandleQueryContentEvent(WidgetQueryContentEvent& aEvent) } aEvent.mReply.mOffset = mIMECaretOffset; - aEvent.mReply.mRect = mIMECaretRect - GetChildProcessOffset(); + aEvent.mReply.mRect = + mIMECaretRect - LayoutDevicePixel::FromUntyped(GetChildProcessOffset()); aEvent.mSucceeded = true; } break; case NS_QUERY_EDITOR_RECT: { - aEvent.mReply.mRect = mIMEEditorRect - GetChildProcessOffset(); + aEvent.mReply.mRect = + mIMEEditorRect - LayoutDevicePixel::FromUntyped(GetChildProcessOffset()); aEvent.mSucceeded = true; } break; diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index 044f1eaa28c9..6150f2487dc3 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -172,9 +172,9 @@ public: const bool& aCausedByComposition) MOZ_OVERRIDE; virtual bool RecvNotifyIMESelectedCompositionRect( const uint32_t& aOffset, - InfallibleTArray&& aRects, + InfallibleTArray&& aRects, const uint32_t& aCaretOffset, - const nsIntRect& aCaretRect) MOZ_OVERRIDE; + const LayoutDeviceIntRect& aCaretRect) MOZ_OVERRIDE; virtual bool RecvNotifyIMESelection(const uint32_t& aSeqno, const uint32_t& aAnchor, const uint32_t& aFocus, @@ -183,11 +183,11 @@ public: virtual bool RecvNotifyIMETextHint(const nsString& aText) MOZ_OVERRIDE; virtual bool RecvNotifyIMEMouseButtonEvent(const widget::IMENotification& aEventMessage, bool* aConsumedByIME) MOZ_OVERRIDE; - virtual bool RecvNotifyIMEEditorRect(const nsIntRect& aRect) MOZ_OVERRIDE; + virtual bool RecvNotifyIMEEditorRect(const LayoutDeviceIntRect& aRect) MOZ_OVERRIDE; virtual bool RecvNotifyIMEPositionChange( - const nsIntRect& aEditoRect, - InfallibleTArray&& aCompositionRects, - const nsIntRect& aCaretRect) MOZ_OVERRIDE; + const LayoutDeviceIntRect& aEditorRect, + InfallibleTArray&& aCompositionRects, + const LayoutDeviceIntRect& aCaretRect) MOZ_OVERRIDE; virtual bool RecvEndIMEComposition(const bool& aCancel, nsString* aComposition) MOZ_OVERRIDE; virtual bool RecvGetInputContext(int32_t* aIMEEnabled, @@ -414,10 +414,10 @@ protected: uint32_t mIMESeqno; uint32_t mIMECompositionRectOffset; - InfallibleTArray mIMECompositionRects; + InfallibleTArray mIMECompositionRects; uint32_t mIMECaretOffset; - nsIntRect mIMECaretRect; - nsIntRect mIMEEditorRect; + LayoutDeviceIntRect mIMECaretRect; + LayoutDeviceIntRect mIMEEditorRect; // The number of event series we're currently capturing. int32_t mEventCaptureDepth; diff --git a/widget/PuppetWidget.cpp b/widget/PuppetWidget.cpp index 4a211dac6273..e1e928010fd1 100644 --- a/widget/PuppetWidget.cpp +++ b/widget/PuppetWidget.cpp @@ -550,13 +550,13 @@ PuppetWidget::NotifyIMEOfUpdateComposition() uint32_t startOffset; uint32_t targetCauseOffset; - nsAutoTArray textRectArray; + nsAutoTArray textRectArray; if (!GetCompositionRects(startOffset, textRectArray, targetCauseOffset)) { return NS_ERROR_FAILURE; } - nsIntRect caretRect; + LayoutDeviceIntRect caretRect; GetCaretRect(caretRect, targetCauseOffset); mTabChild->SendNotifyIMESelectedCompositionRect(startOffset, @@ -568,7 +568,7 @@ PuppetWidget::NotifyIMEOfUpdateComposition() bool PuppetWidget::GetCompositionRects(uint32_t& aStartOffset, - nsTArray& aTextRectArray, + nsTArray& aTextRectArray, uint32_t& aTargetCauseOffset) { nsRefPtr textComposition = @@ -605,7 +605,7 @@ PuppetWidget::GetCaretOffset() } bool -PuppetWidget::GetCaretRect(nsIntRect& aCaretRect, uint32_t aCaretOffset) +PuppetWidget::GetCaretRect(LayoutDeviceIntRect& aCaretRect, uint32_t aCaretOffset) { nsEventStatus status; WidgetQueryContentEvent caretRect(true, NS_QUERY_CARET_RECT, this); @@ -629,7 +629,7 @@ PuppetWidget::NotifyIMEOfEditorRect() return NS_ERROR_FAILURE; } - nsIntRect rect; + LayoutDeviceIntRect rect; if (!GetEditorRect(rect)) { return NS_ERROR_FAILURE; } @@ -638,7 +638,7 @@ PuppetWidget::NotifyIMEOfEditorRect() } bool -PuppetWidget::GetEditorRect(nsIntRect& aRect) +PuppetWidget::GetEditorRect(LayoutDeviceIntRect& aRect) { nsEventStatus status; WidgetQueryContentEvent editorRectEvent(true, NS_QUERY_EDITOR_RECT, this); @@ -761,14 +761,14 @@ PuppetWidget::NotifyIMEOfPositionChange() return NS_ERROR_FAILURE; } - nsIntRect editorRect; + LayoutDeviceIntRect editorRect; if (!GetEditorRect(editorRect)) { return NS_ERROR_FAILURE; } uint32_t startOffset; uint32_t targetCauseOffset; - nsAutoTArray textRectArray; + nsAutoTArray textRectArray; if (!GetCompositionRects(startOffset, textRectArray, targetCauseOffset)) { @@ -776,7 +776,7 @@ PuppetWidget::NotifyIMEOfPositionChange() targetCauseOffset = GetCaretOffset(); } - nsIntRect caretRect; + LayoutDeviceIntRect caretRect; GetCaretRect(caretRect, targetCauseOffset); if (!mTabChild->SendNotifyIMEPositionChange(editorRect, textRectArray, caretRect)) { diff --git a/widget/PuppetWidget.h b/widget/PuppetWidget.h index 95f9b77083f5..9f9a04883d61 100644 --- a/widget/PuppetWidget.h +++ b/widget/PuppetWidget.h @@ -221,11 +221,11 @@ private: nsresult NotifyIMEOfEditorRect(); nsresult NotifyIMEOfPositionChange(); - bool GetEditorRect(nsIntRect& aEditorRect); + bool GetEditorRect(mozilla::LayoutDeviceIntRect& aEditorRect); bool GetCompositionRects(uint32_t& aStartOffset, - nsTArray& aRectArray, + nsTArray& aRectArray, uint32_t& aTargetCauseOffset); - bool GetCaretRect(nsIntRect& aCaretRect, uint32_t aCaretOffset); + bool GetCaretRect(mozilla::LayoutDeviceIntRect& aCaretRect, uint32_t aCaretOffset); uint32_t GetCaretOffset(); class PaintTask : public nsRunnable { diff --git a/widget/TextEvents.h b/widget/TextEvents.h index 1367b5c38cec..76174226602a 100644 --- a/widget/TextEvents.h +++ b/widget/TextEvents.h @@ -492,7 +492,7 @@ public: uint32_t mOffset; nsString mString; // Finally, the coordinates is system coordinates. - nsIntRect mRect; + mozilla::LayoutDeviceIntRect mRect; // The return widget has the caret. This is set at all query events. nsIWidget* mFocusedWidget; // true if selection is reversed (end < start) diff --git a/widget/cocoa/TextInputHandler.mm b/widget/cocoa/TextInputHandler.mm index 41da67b6e498..db791e9bf47b 100644 --- a/widget/cocoa/TextInputHandler.mm +++ b/widget/cocoa/TextInputHandler.mm @@ -3118,7 +3118,7 @@ IMEInputHandler::FirstRectForCharacterRange(NSRange& aRange, nsRefPtr kungFuDeathGrip(this); - nsIntRect r; + LayoutDeviceIntRect r; bool useCaretRect = (aRange.length == 0); if (!useCaretRect) { WidgetQueryContentEvent charRect(true, NS_QUERY_TEXT_RECT, mWidget); @@ -3154,7 +3154,8 @@ IMEInputHandler::FirstRectForCharacterRange(NSRange& aRange, if (!rootWindow || !rootView) { return rect; } - rect = nsCocoaUtils::DevPixelsToCocoaPoints(r, mWidget->BackingScaleFactor()); + rect = nsCocoaUtils::DevPixelsToCocoaPoints(LayoutDevicePixel::ToUntyped(r), + mWidget->BackingScaleFactor()); rect = [rootView convertRect:rect toView:nil]; rect.origin = [rootWindow convertBaseToScreen:rect.origin]; diff --git a/widget/windows/nsIMM32Handler.cpp b/widget/windows/nsIMM32Handler.cpp index 7eb9bd321e5e..e7c090ba724d 100644 --- a/widget/windows/nsIMM32Handler.cpp +++ b/widget/windows/nsIMM32Handler.cpp @@ -1805,7 +1805,7 @@ nsIMM32Handler::GetCharacterRectOfSelectedTextAt(nsWindow* aWindow, aWindow->InitEvent(charRect, &point); aWindow->DispatchWindowEvent(&charRect); if (charRect.mSucceeded) { - aCharRect = charRect.mReply.mRect; + aCharRect = LayoutDevicePixel::ToUntyped(charRect.mReply.mRect); PR_LOG(gIMM32Log, PR_LOG_ALWAYS, ("IMM32: GetCharacterRectOfSelectedTextAt, aOffset=%lu, SUCCEEDED\n", aOffset)); @@ -1844,7 +1844,7 @@ nsIMM32Handler::GetCaretRect(nsWindow* aWindow, nsIntRect &aCaretRect) ("IMM32: GetCaretRect, FAILED (NS_QUERY_CARET_RECT)\n")); return false; } - aCaretRect = caretRect.mReply.mRect; + aCaretRect = LayoutDevicePixel::ToUntyped(caretRect.mReply.mRect); PR_LOG(gIMM32Log, PR_LOG_ALWAYS, ("IMM32: GetCaretRect, SUCCEEDED, aCaretRect={ x: %ld, y: %ld, width: %ld, height: %ld }\n", aCaretRect.x, aCaretRect.y, aCaretRect.width, aCaretRect.height)); @@ -1956,8 +1956,8 @@ nsIMM32Handler::SetIMERelatedWindowsPosOnPlugin(nsWindow* aWindow, // Clip the plugin rect by the client rect of the window because composition // window needs to be specified the position in the client area. nsWindow* toplevelWindow = aWindow->GetTopLevelWindow(false); - nsIntRect pluginRectInScreen = - editorRectEvent.mReply.mRect + toplevelWindow->WidgetToScreenOffsetUntyped(); + LayoutDeviceIntRect pluginRectInScreen = + editorRectEvent.mReply.mRect + toplevelWindow->WidgetToScreenOffset(); nsIntRect winRectInScreen; aWindow->GetClientBounds(winRectInScreen); // composition window cannot be positioned on the edge of client area. diff --git a/widget/windows/nsTextStore.cpp b/widget/windows/nsTextStore.cpp index ae7d53a8b0fb..cddb12b4baf6 100644 --- a/widget/windows/nsTextStore.cpp +++ b/widget/windows/nsTextStore.cpp @@ -3198,7 +3198,7 @@ nsTextStore::GetTextExt(TsViewCookie vcView, return E_FAIL; } - event.mReply.mRect.MoveBy(refWindow->WidgetToScreenOffsetUntyped()); + event.mReply.mRect.MoveBy(refWindow->WidgetToScreenOffset()); } // get bounding screen rect to test for clipping @@ -3334,7 +3334,7 @@ nsTextStore::GetScreenExtInternal(RECT &aScreenExt) boundRect.MoveTo(0, 0); // Clip frame rect to window rect - boundRect.IntersectRect(event.mReply.mRect, boundRect); + boundRect.IntersectRect(LayoutDevicePixel::ToUntyped(event.mReply.mRect), boundRect); if (!boundRect.IsEmpty()) { boundRect.MoveBy(refWindow->WidgetToScreenOffsetUntyped()); ::SetRect(&aScreenExt, boundRect.x, boundRect.y, @@ -4305,7 +4305,7 @@ nsTextStore::CreateNativeCaret() return; } - nsIntRect& caretRect = queryCaretRect.mReply.mRect; + LayoutDeviceIntRect& caretRect = queryCaretRect.mReply.mRect; mNativeCaretIsCreated = ::CreateCaret(mWidget->GetWindowHandle(), nullptr, caretRect.width, caretRect.height); if (!mNativeCaretIsCreated) { @@ -4325,8 +4325,8 @@ nsTextStore::CreateNativeCaret() } if (toplevelWindow != window) { - caretRect.MoveBy(toplevelWindow->WidgetToScreenOffsetUntyped()); - caretRect.MoveBy(-window->WidgetToScreenOffsetUntyped()); + caretRect.MoveBy(toplevelWindow->WidgetToScreenOffset()); + caretRect.MoveBy(-window->WidgetToScreenOffset()); } ::SetCaretPos(caretRect.x, caretRect.y); From 348ef34fe4fc22112d0572252eb66d2bef79c1ad Mon Sep 17 00:00:00 2001 From: Chris Pearce Date: Thu, 5 Feb 2015 09:36:44 +1300 Subject: [PATCH 07/74] Bug 1129229 - Recognize com.adobe.primetime keysystem string. r=edwin --- dom/media/eme/MediaKeySystemAccess.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dom/media/eme/MediaKeySystemAccess.cpp b/dom/media/eme/MediaKeySystemAccess.cpp index 9e619e84f007..e57f2d6c821e 100644 --- a/dom/media/eme/MediaKeySystemAccess.cpp +++ b/dom/media/eme/MediaKeySystemAccess.cpp @@ -107,11 +107,12 @@ MediaKeySystemAccess::IsKeySystemSupported(const nsAString& aKeySystem) } #ifdef XP_WIN - if (aKeySystem.EqualsLiteral("com.adobe.access") && + if ((aKeySystem.EqualsLiteral("com.adobe.access") || + aKeySystem.EqualsLiteral("com.adobe.primetime")) && Preferences::GetBool("media.eme.adobe-access.enabled", false) && IsVistaOrLater() && // Win Vista and later only. HaveGMPFor(mps, - NS_LITERAL_CSTRING("com.adobe.access"), + NS_ConvertUTF16toUTF8(aKeySystem), NS_LITERAL_CSTRING(GMP_API_DECRYPTOR))) { return true; } From 7a4a2758f6f6e22b7069839b24fab3c921a754e2 Mon Sep 17 00:00:00 2001 From: Till Schneidereit Date: Thu, 29 Jan 2015 16:40:49 +0100 Subject: [PATCH 08/74] Bug 1127169 - Use self-hosting internal List type for TypedObject functions' internal bookkeeping. r=nmatsakis --HG-- extra : rebase_source : de08f4c63f55b91e35066a94ce4f05b9f3028a3b --- js/src/builtin/TypedObject.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/js/src/builtin/TypedObject.js b/js/src/builtin/TypedObject.js index 46daea7730e7..06240fc63509 100644 --- a/js/src/builtin/TypedObject.js +++ b/js/src/builtin/TypedObject.js @@ -740,7 +740,8 @@ function BuildTypedSeqImpl(arrayType, len, depth, func) { // Create a zeroed instance with no data var result = new arrayType(); - var indices = NewDenseArray(depth); + var indices = new List(); + indices.length = depth; for (var i = 0; i < depth; i++) { indices[i] = 0; } @@ -772,7 +773,8 @@ function ComputeIterationSpace(arrayType, depth, len) { assert(IsObject(arrayType) && ObjectIsTypeDescr(arrayType), "ComputeIterationSpace called on non-type-object"); assert(TypeDescrIsArrayType(arrayType), "ComputeIterationSpace called on non-array-type"); assert(depth > 0, "ComputeIterationSpace called on non-positive depth"); - var iterationSpace = NewDenseArray(depth); + var iterationSpace = new List(); + iterationSpace.length = depth; iterationSpace[0] = len; var totalLength = len; var grainType = arrayType.elementType; From fdee1bb8805c558e485332d53a966cc91c47f174 Mon Sep 17 00:00:00 2001 From: Bas Schouten Date: Wed, 4 Feb 2015 22:03:21 +0100 Subject: [PATCH 09/74] Bug 1083245: Pop all clips before copying to the destination blending surface. r=jrmuizel We need to pop the clips from the decide context before flushing and copying to the destination blending surface, otherwise drawing commands executed on a pushed layer for clipping will not be realized on the destination surface for blending. Note that this fixes most situation, but in the case of doing custom blending to an area of a surface which is not opaque while having a complex clip pushed this will still lead to some artifacts. I haven't seen this be a problem in practice though. --- gfx/2d/DrawTargetD2D1.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gfx/2d/DrawTargetD2D1.cpp b/gfx/2d/DrawTargetD2D1.cpp index e21c58fbe071..00bb0b34d5bc 100644 --- a/gfx/2d/DrawTargetD2D1.cpp +++ b/gfx/2d/DrawTargetD2D1.cpp @@ -968,6 +968,8 @@ DrawTargetD2D1::FinalizeDrawing(CompositionOp aOp, const Pattern &aPattern) mDC->CreateBitmap(D2DIntSize(mSize), D2D1::BitmapProperties(D2DPixelFormat(mFormat)), byRef(tmpBitmap)); // This flush is important since the copy method will not know about the context drawing to the surface. + // We also need to pop all the clips to make sure any drawn content will have made it to the final bitmap. + PopAllClips(); mDC->Flush(); // We need to use a copy here because affects don't accept a surface on @@ -978,6 +980,9 @@ DrawTargetD2D1::FinalizeDrawing(CompositionOp aOp, const Pattern &aPattern) mBlendEffect->SetInput(1, mTempBitmap); mBlendEffect->SetValue(D2D1_BLEND_PROP_MODE, D2DBlendMode(aOp)); + PushClipsToDC(mDC); + mClipsArePushed = true; + mDC->DrawImage(mBlendEffect, D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR, D2D1_COMPOSITE_MODE_BOUNDED_SOURCE_COPY); return; } From 6225c3b5b85f5f84d1dcd433bdedfdc248f9ad4b Mon Sep 17 00:00:00 2001 From: Mason Chang Date: Wed, 4 Feb 2015 13:08:31 -0800 Subject: [PATCH 10/74] Bug 1128691. Part 1: Consolidate vsync compositor pref checks. r=benwa --- gfx/layers/ipc/CompositorParent.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/gfx/layers/ipc/CompositorParent.cpp b/gfx/layers/ipc/CompositorParent.cpp index 5e9897ab7258..286238553b4d 100644 --- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -416,6 +416,7 @@ CompositorParent::CompositorParent(nsIWidget* aWidget, , mOverrideComposeReadiness(false) , mForceCompositionTask(nullptr) , mCompositorThreadHolder(sCompositorThreadHolder) + , mCompositorVsyncObserver(nullptr) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(CompositorThread(), @@ -577,7 +578,7 @@ CompositorParent::RecvMakeSnapshot(const SurfaceDescriptor& aInSnapshot, bool CompositorParent::RecvFlushRendering() { - if (gfxPrefs::VsyncAlignedCompositor() && mCompositorVsyncObserver->NeedsComposite()) { + if (mCompositorVsyncObserver && mCompositorVsyncObserver->NeedsComposite()) { mCompositorVsyncObserver->SetNeedsComposite(false); CancelCurrentCompositeTask(); ForceComposeToTarget(nullptr); @@ -718,7 +719,7 @@ CompositorParent::ForceComposition() void CompositorParent::CancelCurrentCompositeTask() { - if (gfxPrefs::VsyncAlignedCompositor()) { + if (mCompositorVsyncObserver) { mCompositorVsyncObserver->CancelCurrentCompositeTask(); } else if (mCurrentCompositeTask) { mCurrentCompositeTask->Cancel(); @@ -831,7 +832,7 @@ CalculateCompositionFrameRate() void CompositorParent::ScheduleSoftwareTimerComposition() { - MOZ_ASSERT(!gfxPrefs::VsyncAlignedCompositor()); + MOZ_ASSERT(!mCompositorVsyncObserver); if (mCurrentCompositeTask) { return; @@ -874,7 +875,7 @@ CompositorParent::ScheduleComposition() return; } - if (gfxPrefs::VsyncAlignedCompositor()) { + if (mCompositorVsyncObserver) { mCompositorVsyncObserver->SetNeedsComposite(true); } else { ScheduleSoftwareTimerComposition(); @@ -884,7 +885,7 @@ CompositorParent::ScheduleComposition() void CompositorParent::CompositeCallback(TimeStamp aScheduleTime) { - if (gfxPrefs::VsyncAlignedCompositor()) { + if (mCompositorVsyncObserver) { // Align OMTA to vsync time. // TODO: ensure it aligns with the refresh / start time of // animations @@ -1097,7 +1098,7 @@ CompositorParent::ShadowLayersUpdated(LayerTransactionParent* aLayerTree, // conditions. bool needTestComposite = mIsTesting && root && (mCurrentCompositeTask || - (gfxPrefs::VsyncAlignedCompositor() && + (mCompositorVsyncObserver && mCompositorVsyncObserver->NeedsComposite())); if (needTestComposite) { AutoResolveRefLayers resolve(mCompositionManager); @@ -1131,7 +1132,7 @@ CompositorParent::SetTestSampleTime(LayerTransactionParent* aLayerTree, mTestTime = aTime; bool testComposite = mCompositionManager && (mCurrentCompositeTask || - (gfxPrefs::VsyncAlignedCompositor() + (mCompositorVsyncObserver && mCompositorVsyncObserver->NeedsComposite())); // Update but only if we were already scheduled to animate From 424409c421faa2273bf418d12e873ae5bb656acf Mon Sep 17 00:00:00 2001 From: Mason Chang Date: Wed, 4 Feb 2015 13:08:40 -0800 Subject: [PATCH 11/74] Bug 1128691. Part 2: Consolidate touch resampilng pref checks. r=kats --- widget/gonk/GeckoTouchDispatcher.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/widget/gonk/GeckoTouchDispatcher.cpp b/widget/gonk/GeckoTouchDispatcher.cpp index 7701b43a0943..6f0cc2221d24 100644 --- a/widget/gonk/GeckoTouchDispatcher.cpp +++ b/widget/gonk/GeckoTouchDispatcher.cpp @@ -122,7 +122,7 @@ GeckoTouchDispatcher::SetCompositorVsyncObserver(mozilla::layers::CompositorVsyn MOZ_ASSERT(NS_IsMainThread()); // We assume on b2g that there is only 1 CompositorParent MOZ_ASSERT(sTouchDispatcher->mCompositorVsyncObserver == nullptr); - if (gfxPrefs::TouchResampling()) { + if (sTouchDispatcher->mResamplingEnabled) { sTouchDispatcher->mCompositorVsyncObserver = aObserver; } } @@ -131,7 +131,7 @@ GeckoTouchDispatcher::SetCompositorVsyncObserver(mozilla::layers::CompositorVsyn /* static */ bool GeckoTouchDispatcher::NotifyVsync(TimeStamp aVsyncTimestamp) { - if ((sTouchDispatcher == nullptr) || !gfxPrefs::TouchResampling()) { + if (sTouchDispatcher == nullptr) { return false; } From ebc54d52b94c13a9beb9cbf16fc13d25ee98da03 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Wed, 4 Feb 2015 13:13:58 -0800 Subject: [PATCH 12/74] Bug 1129247 - Introduce MOZ_DIAGNOSTIC_ASSERT. r=Waldo --- mfbt/Assertions.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/mfbt/Assertions.h b/mfbt/Assertions.h index 5443329a545a..6836f2d95a04 100644 --- a/mfbt/Assertions.h +++ b/mfbt/Assertions.h @@ -294,6 +294,13 @@ __declspec(noreturn) __inline void MOZ_NoReturn() {} * MOZ_ASSERT has no effect in non-debug builds. It is designed to catch bugs * *only* during debugging, not "in the field". If you want the latter, use * MOZ_RELEASE_ASSERT, which applies to non-debug builds as well. + * + * MOZ_DIAGNOSTIC_ASSERT works like MOZ_RELEASE_ASSERT in Nightly/Aurora and + * MOZ_ASSERT in Beta/Release - use this when a condition is potentially rare + * enough to require real user testing to hit, but is not security-sensitive. + * This can cause user pain, so use it sparingly. If a MOZ_DIAGNOSTIC_ASSERT + * is firing, it should promptly be converted to a MOZ_ASSERT while the failure + * is being investigated, rather than letting users suffer. */ /* @@ -378,6 +385,12 @@ struct AssertionConditionType # define MOZ_ASSERT(...) do { } while (0) #endif /* DEBUG */ +#ifdef RELEASE_BUILD +# define MOZ_DIAGNOSTIC_ASSERT MOZ_ASSERT +#else +# define MOZ_DIAGNOSTIC_ASSERT MOZ_RELEASE_ASSERT +#endif + /* * MOZ_ASSERT_IF(cond1, cond2) is equivalent to MOZ_ASSERT(cond2) if cond1 is * true. From 8f668dcd1365c078bd611b912e0e97c343f3f944 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Wed, 4 Feb 2015 13:13:59 -0800 Subject: [PATCH 13/74] Bug 1129247 - Use MOZ_DIAGNOSTIC_ASSERT instead of MOZ_RELEASE_ASSERT in media code. r=mattwoodrow --- dom/media/MediaPromise.h | 10 +++++----- dom/media/mediasource/MediaSourceReader.cpp | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/dom/media/MediaPromise.h b/dom/media/MediaPromise.h index faef40729f2c..628b0f85a648 100644 --- a/dom/media/MediaPromise.h +++ b/dom/media/MediaPromise.h @@ -94,7 +94,7 @@ public: void Disconnect() { AssertOnDispatchThread(); - MOZ_RELEASE_ASSERT(!mComplete); + MOZ_DIAGNOSTIC_ASSERT(!mComplete); mDisconnected = true; } @@ -302,7 +302,7 @@ public: ResolveMethodType aResolveMethod, RejectMethodType aRejectMethod) { MutexAutoLock lock(mMutex); - MOZ_RELEASE_ASSERT(!IsExclusive || !mHaveConsumer); + MOZ_DIAGNOSTIC_ASSERT(!IsExclusive || !mHaveConsumer); mHaveConsumer = true; nsRefPtr thenValue = new ThenValue(aResponseTarget, aThisVal, @@ -332,7 +332,7 @@ public: void ChainTo(already_AddRefed aChainedPromise, const char* aCallSite) { MutexAutoLock lock(mMutex); - MOZ_RELEASE_ASSERT(!IsExclusive || !mHaveConsumer); + MOZ_DIAGNOSTIC_ASSERT(!IsExclusive || !mHaveConsumer); mHaveConsumer = true; nsRefPtr chainedPromise = aChainedPromise; PROMISE_LOG("%s invoking Chain() [this=%p, chainedPromise=%p, isPending=%d]", @@ -507,13 +507,13 @@ public: void Begin(already_AddRefed aConsumer) { - MOZ_RELEASE_ASSERT(!Exists()); + MOZ_DIAGNOSTIC_ASSERT(!Exists()); mConsumer = aConsumer; } void Complete() { - MOZ_RELEASE_ASSERT(Exists()); + MOZ_DIAGNOSTIC_ASSERT(Exists()); mConsumer = nullptr; } diff --git a/dom/media/mediasource/MediaSourceReader.cpp b/dom/media/mediasource/MediaSourceReader.cpp index 8fae73e89967..ff1dc3c1e895 100644 --- a/dom/media/mediasource/MediaSourceReader.cpp +++ b/dom/media/mediasource/MediaSourceReader.cpp @@ -123,7 +123,7 @@ MediaSourceReader::RequestAudioData() mAudioPromise.Reject(CANCELED, __func__); return p; } - MOZ_RELEASE_ASSERT(!mAudioSeekRequest.Exists()); + MOZ_DIAGNOSTIC_ASSERT(!mAudioSeekRequest.Exists()); SwitchReaderResult ret = SwitchAudioReader(mLastAudioTime); switch (ret) { @@ -157,7 +157,7 @@ void MediaSourceReader::DoAudioRequest() void MediaSourceReader::OnAudioDecoded(AudioData* aSample) { - MOZ_RELEASE_ASSERT(!IsSeeking()); + MOZ_DIAGNOSTIC_ASSERT(!IsSeeking()); mAudioRequest.Complete(); MSE_DEBUGV("MediaSourceReader(%p)::OnAudioDecoded [mTime=%lld mDuration=%lld mDiscontinuity=%d]", @@ -209,7 +209,7 @@ AdjustEndTime(int64_t* aEndTime, MediaDecoderReader* aReader) void MediaSourceReader::OnAudioNotDecoded(NotDecodedReason aReason) { - MOZ_RELEASE_ASSERT(!IsSeeking()); + MOZ_DIAGNOSTIC_ASSERT(!IsSeeking()); mAudioRequest.Complete(); MSE_DEBUG("MediaSourceReader(%p)::OnAudioNotDecoded aReason=%u IsEnded: %d", this, aReason, IsEnded()); @@ -259,7 +259,7 @@ MediaSourceReader::RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThres mVideoPromise.Reject(CANCELED, __func__); return p; } - MOZ_RELEASE_ASSERT(!mVideoSeekRequest.Exists()); + MOZ_DIAGNOSTIC_ASSERT(!mVideoSeekRequest.Exists()); SwitchReaderResult ret = SwitchVideoReader(mLastVideoTime); switch (ret) { @@ -295,7 +295,7 @@ MediaSourceReader::DoVideoRequest() void MediaSourceReader::OnVideoDecoded(VideoData* aSample) { - MOZ_RELEASE_ASSERT(!IsSeeking()); + MOZ_DIAGNOSTIC_ASSERT(!IsSeeking()); mVideoRequest.Complete(); MSE_DEBUGV("MediaSourceReader(%p)::OnVideoDecoded [mTime=%lld mDuration=%lld mDiscontinuity=%d]", @@ -319,7 +319,7 @@ MediaSourceReader::OnVideoDecoded(VideoData* aSample) void MediaSourceReader::OnVideoNotDecoded(NotDecodedReason aReason) { - MOZ_RELEASE_ASSERT(!IsSeeking()); + MOZ_DIAGNOSTIC_ASSERT(!IsSeeking()); mVideoRequest.Complete(); MSE_DEBUG("MediaSourceReader(%p)::OnVideoNotDecoded aReason=%u IsEnded: %d", this, aReason, IsEnded()); From b657260fda839675f3552d032c8d943479e909f3 Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Wed, 4 Feb 2015 08:40:56 -0500 Subject: [PATCH 14/74] Bug 1129394 - produce a useful error message for |mach build-backend| without having run configure; r=ted.mielczarek Checking for config.status ourselves avoids the unpleasant situation of the subprocess module checking for us and producing a cryptic error message. --- python/mozbuild/mozbuild/mach_commands.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/python/mozbuild/mozbuild/mach_commands.py b/python/mozbuild/mozbuild/mach_commands.py index 5d88585e1d34..26b7dda2798d 100644 --- a/python/mozbuild/mozbuild/mach_commands.py +++ b/python/mozbuild/mozbuild/mach_commands.py @@ -586,6 +586,12 @@ class Build(MachCommandBase): python = self.virtualenv_manager.python_path config_status = os.path.join(self.topobjdir, 'config.status') + if not os.path.exists(config_status): + print('config.status not found. Please run |mach configure| ' + 'or |mach build| prior to building the %s build backend.' + % backend) + return 1 + args = [python, config_status, '--backend=%s' % backend] if diff: args.append('--diff') From 52c52854d63c98be1ce43e1cf32bf076b63df684 Mon Sep 17 00:00:00 2001 From: Chris Manchester Date: Mon, 2 Feb 2015 13:32:49 -0500 Subject: [PATCH 15/74] Bug 1128584 - Only log valid status values when processing errors in xpcshell's head.js;r=ted --- testing/xpcshell/head.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testing/xpcshell/head.js b/testing/xpcshell/head.js index 736892e891b1..be9ce8e5d1e5 100644 --- a/testing/xpcshell/head.js +++ b/testing/xpcshell/head.js @@ -653,8 +653,8 @@ function do_execute_soon(callback, aName) { let stack = e.stack ? _format_stack(e.stack) : null; _testLogger.testStatus(_TEST_NAME, funcName, - 'ERROR', - 'OK', + 'FAIL', + 'PASS', _exception_message(e), stack); _do_quit(); From 80d28441f04ce40902993506875374c897fa5091 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Wed, 4 Feb 2015 13:34:18 -0800 Subject: [PATCH 16/74] Bug 1129559 - Implement move construction for mozilla::MaybeOneOf; r=jandem --- mfbt/MaybeOneOf.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/mfbt/MaybeOneOf.h b/mfbt/MaybeOneOf.h index af9c294459c4..9c38ff8b039d 100644 --- a/mfbt/MaybeOneOf.h +++ b/mfbt/MaybeOneOf.h @@ -51,6 +51,29 @@ public: MaybeOneOf() : state(None) {} ~MaybeOneOf() { destroyIfConstructed(); } + MaybeOneOf(MaybeOneOf&& rhs) + : state(None) + { + if (!rhs.empty()) { + if (rhs.constructed()) { + construct(Move(rhs.as())); + rhs.as().~T1(); + } else { + construct(Move(rhs.as())); + rhs.as().~T2(); + } + rhs.state = None; + } + } + + MaybeOneOf &operator=(MaybeOneOf&& rhs) + { + MOZ_ASSERT(this != &rhs, "Self-move is prohibited"); + this->~MaybeOneOf(); + new(this) MaybeOneOf(Move(rhs)); + return *this; + } + bool empty() const { return state == None; } template From 72874b667cc9a6badcc673bdfc205bee9196ce1f Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Wed, 4 Feb 2015 13:40:01 -0800 Subject: [PATCH 17/74] Bug 1128653 - Make the native code bounds of optimization regions closed. (r=djvj) --- js/src/jit/OptimizationTracking.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/js/src/jit/OptimizationTracking.cpp b/js/src/jit/OptimizationTracking.cpp index f0dedd994d7d..a416dabb0e66 100644 --- a/js/src/jit/OptimizationTracking.cpp +++ b/js/src/jit/OptimizationTracking.cpp @@ -475,6 +475,12 @@ IonTrackedOptimizationsRegion::findAttemptsIndex(uint32_t offset) const Maybe IonTrackedOptimizationsRegionTable::findRegion(uint32_t offset) const { + // For two contiguous regions, e.g., [i, j] and [j, k], an offset exactly + // at j will be associated with [i, j] instead of [j, k]. An offset + // exactly at j is often a return address from a younger frame, which case + // the next region, despite starting at j, has not yet logically started + // execution. + static const uint32_t LINEAR_SEARCH_THRESHOLD = 8; uint32_t regions = numEntries(); MOZ_ASSERT(regions > 0); @@ -483,7 +489,7 @@ IonTrackedOptimizationsRegionTable::findRegion(uint32_t offset) const if (regions <= LINEAR_SEARCH_THRESHOLD) { for (uint32_t i = 0; i < regions; i++) { IonTrackedOptimizationsRegion region = entry(i); - if (region.startOffset() <= offset && offset < region.endOffset()) { + if (region.startOffset() <= offset && offset <= region.endOffset()) { return Some(entry(i)); } } @@ -500,7 +506,7 @@ IonTrackedOptimizationsRegionTable::findRegion(uint32_t offset) const if (offset < region.startOffset()) { // Entry is below mid. regions = step; - } else if (offset >= region.endOffset()) { + } else if (offset > region.endOffset()) { // Entry is above mid. i = mid; regions -= step; @@ -703,14 +709,14 @@ IonTrackedOptimizationsRegion::WriteRun(CompactBufferWriter &writer, const UniqueTrackedOptimizations &unique) { // Write the header, which is the range that this whole run encompasses. - JitSpew(JitSpew_OptimizationTracking, " Header: [%u, %u)", + JitSpew(JitSpew_OptimizationTracking, " Header: [%u, %u]", start->startOffset.offset(), (end - 1)->endOffset.offset()); writer.writeUnsigned(start->startOffset.offset()); writer.writeUnsigned((end - 1)->endOffset.offset()); // Write the first entry of the run, which is not delta-encoded. JitSpew(JitSpew_OptimizationTracking, - " [%6u, %6u) vector %3u, offset %4u", + " [%6u, %6u] vector %3u, offset %4u", start->startOffset.offset(), start->endOffset.offset(), unique.indexOf(start->optimizations), writer.length()); uint32_t prevEndOffset = start->endOffset.offset(); @@ -727,7 +733,7 @@ IonTrackedOptimizationsRegion::WriteRun(CompactBufferWriter &writer, uint8_t index = unique.indexOf(entry->optimizations); JitSpew(JitSpew_OptimizationTracking, - " [%6u, %6u) delta [+%5u, +%5u) vector %3u, offset %4u", + " [%6u, %6u] delta [+%5u, +%5u] vector %3u, offset %4u", startOffset, endOffset, startDelta, length, index, writer.length()); WriteDelta(writer, startDelta, length, index); From e0aee2d0b6b58fc9d46b7a10af873c417deaa5eb Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Wed, 4 Feb 2015 13:40:02 -0800 Subject: [PATCH 18/74] Bug 1127156 - Rework optimization tracking JSAPI to be more usable from the profiler. (r=djvj) --- js/public/ProfilingFrameIterator.h | 2 + js/public/TrackedOptimizationInfo.h | 316 +++++++++++++++ js/src/jit/CodeGenerator.cpp | 2 +- js/src/jit/IonBuilder.cpp | 4 + js/src/jit/IonBuilder.h | 16 +- js/src/jit/JitcodeMap.h | 63 ++- js/src/jit/MCallOptimize.cpp | 4 + js/src/jit/OptimizationTracking.cpp | 329 ++++++++++++---- js/src/jit/OptimizationTracking.h | 424 +++++---------------- js/src/jit/shared/CodeGenerator-shared.cpp | 62 ++- js/src/jit/shared/CodeGenerator-shared.h | 26 +- js/src/jsapi-tests/testIntTypesABI.cpp | 1 + js/src/jscntxt.h | 4 + js/src/jsinfer.cpp | 84 ++-- js/src/jsinfer.h | 2 + js/src/moz.build | 1 + js/src/vm/Stack.cpp | 2 + 17 files changed, 880 insertions(+), 462 deletions(-) create mode 100644 js/public/TrackedOptimizationInfo.h diff --git a/js/public/ProfilingFrameIterator.h b/js/public/ProfilingFrameIterator.h index 4f48034318a4..0cbe2172d2c5 100644 --- a/js/public/ProfilingFrameIterator.h +++ b/js/public/ProfilingFrameIterator.h @@ -103,6 +103,8 @@ class JS_PUBLIC_API(ProfilingFrameIterator) void *returnAddress; void *activation; const char *label; + bool hasTrackedOptimizations; + uint8_t trackedOptimizationIndex; }; uint32_t extractStack(Frame *frames, uint32_t offset, uint32_t end) const; diff --git a/js/public/TrackedOptimizationInfo.h b/js/public/TrackedOptimizationInfo.h new file mode 100644 index 000000000000..7d3626b38adb --- /dev/null +++ b/js/public/TrackedOptimizationInfo.h @@ -0,0 +1,316 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sts=4 et sw=4 tw=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/. */ + +#ifndef js_TrackedOptimizationInfo_h +#define js_TrackedOptimizationInfo_h + +namespace JS { + +#define TRACKED_STRATEGY_LIST(_) \ + _(GetProp_ArgumentsLength, \ + "getprop arguments.length") \ + _(GetProp_ArgumentsCallee, \ + "getprop arguments.callee") \ + _(GetProp_InferredConstant, \ + "getprop inferred constant") \ + _(GetProp_Constant, \ + "getprop constant") \ + _(GetProp_TypedObject, \ + "getprop TypedObject") \ + _(GetProp_DefiniteSlot, \ + "getprop definite slot") \ + _(GetProp_Unboxed, \ + "getprop unboxed object") \ + _(GetProp_CommonGetter, \ + "getprop common getter") \ + _(GetProp_InlineAccess, \ + "getprop inline access") \ + _(GetProp_Innerize, \ + "getprop innerize (access on global window)") \ + _(GetProp_InlineCache, \ + "getprop IC") \ + \ + _(SetProp_CommonSetter, \ + "setprop common setter") \ + _(SetProp_TypedObject, \ + "setprop TypedObject") \ + _(SetProp_DefiniteSlot, \ + "setprop definite slot") \ + _(SetProp_Unboxed, \ + "setprop unboxed object") \ + _(SetProp_InlineAccess, \ + "setprop inline access") \ + \ + _(GetElem_TypedObject, \ + "getprop TypedObject") \ + _(GetElem_Dense, \ + "getelem dense") \ + _(GetElem_TypedStatic, \ + "getelem TypedArray static") \ + _(GetElem_TypedArray, \ + "getelem TypedArray") \ + _(GetElem_String, \ + "getelem string") \ + _(GetElem_Arguments, \ + "getelem arguments") \ + _(GetElem_ArgumentsInlined, \ + "getelem arguments inlined") \ + _(GetElem_InlineCache, \ + "getelem IC") \ + \ + _(SetElem_TypedObject, \ + "setelem TypedObject") \ + _(SetElem_TypedStatic, \ + "setelem TypedArray static") \ + _(SetElem_TypedArray, \ + "setelem TypedArray") \ + _(SetElem_Dense, \ + "setelem dense") \ + _(SetElem_Arguments, \ + "setelem arguments") \ + _(SetElem_InlineCache, \ + "setelem IC") \ + \ + _(Call_Inline, \ + "call inline") + + +// Ordering is important below. All outcomes before GenericSuccess will be +// considered failures, and all outcomes after GenericSuccess will be +// considered successes. +#define TRACKED_OUTCOME_LIST(_) \ + _(GenericFailure, \ + "failure") \ + _(Disabled, \ + "disabled") \ + _(NoTypeInfo, \ + "no type info") \ + _(NoAnalysisInfo, \ + "no newscript analysis") \ + _(NoShapeInfo, \ + "cannot determine shape") \ + _(UnknownObject, \ + "unknown object") \ + _(UnknownProperties, \ + "unknown properties") \ + _(Singleton, \ + "is singleton") \ + _(NotSingleton, \ + "is not singleton") \ + _(NotFixedSlot, \ + "property not in fixed slot") \ + _(InconsistentFixedSlot, \ + "property not in a consistent fixed slot") \ + _(NotObject, \ + "not definitely an object") \ + _(NotStruct, \ + "not definitely a TypedObject struct") \ + _(NotUnboxed, \ + "not definitely an unboxed object") \ + _(StructNoField, \ + "struct doesn't definitely have field") \ + _(InconsistentFieldType, \ + "unboxed property does not have consistent type") \ + _(InconsistentFieldOffset, \ + "unboxed property does not have consistent offset") \ + _(NeedsTypeBarrier, \ + "needs type barrier") \ + _(InDictionaryMode, \ + "object in dictionary mode") \ + _(NoProtoFound, \ + "no proto found") \ + _(MultiProtoPaths, \ + "not all paths to property go through same proto") \ + _(NonWritableProperty, \ + "non-writable property") \ + _(ProtoIndexedProps, \ + "prototype has indexed properties") \ + _(ArrayBadFlags, \ + "array observed to be sparse, overflowed .length, or has been iterated") \ + _(ArrayDoubleConversion, \ + "array has ambiguous double conversion") \ + _(ArrayRange, \ + "array range issue (.length problems)") \ + _(ArraySeenNegativeIndex, \ + "has seen array access with negative index") \ + _(TypedObjectNeutered, \ + "TypedObject might have been neutered") \ + _(TypedObjectArrayRange, \ + "TypedObject array of unknown length") \ + _(AccessNotDense, \ + "access not on dense native (check receiver, index, and result types)") \ + _(AccessNotTypedObject, \ + "access not on typed array (check receiver and index types)") \ + _(AccessNotTypedArray, \ + "access not on typed array (check receiver, index, and result types)") \ + _(AccessNotString, \ + "getelem not on string (check receiver and index types)") \ + _(StaticTypedArrayUint32, \ + "static uint32 arrays currently cannot be optimized") \ + _(StaticTypedArrayCantComputeMask, \ + "can't compute mask for static typed array access (index isn't constant or not int32)") \ + _(OutOfBounds, \ + "observed out of bounds access") \ + _(GetElemStringNotCached, \ + "getelem on strings is not inline cached") \ + _(NonNativeReceiver, \ + "observed non-native receiver") \ + _(IndexType, \ + "index type must be int32, string, or symbol") \ + _(SetElemNonDenseNonTANotCached, \ + "setelem on non-dense non-TAs are not inline cached") \ + \ + _(CantInlineGeneric, \ + "can't inline") \ + _(CantInlineNoTarget, \ + "can't inline: no target") \ + _(CantInlineNotInterpreted, \ + "can't inline: not interpreted") \ + _(CantInlineNoBaseline, \ + "can't inline: no baseline code") \ + _(CantInlineLazy, \ + "can't inline: lazy script") \ + _(CantInlineNotConstructor, \ + "can't inline: calling non-constructor with 'new'") \ + _(CantInlineDisabledIon, \ + "can't inline: ion disabled for callee") \ + _(CantInlineTooManyArgs, \ + "can't inline: too many arguments") \ + _(CantInlineRecursive, \ + "can't inline: recursive") \ + _(CantInlineHeavyweight, \ + "can't inline: heavyweight") \ + _(CantInlineNeedsArgsObj, \ + "can't inline: needs arguments object") \ + _(CantInlineDebuggee, \ + "can't inline: debuggee") \ + _(CantInlineUnknownProps, \ + "can't inline: type has unknown properties") \ + _(CantInlineExceededDepth, \ + "can't inline: exceeded inlining depth") \ + _(CantInlineBigLoop, \ + "can't inline: big function with a loop") \ + _(CantInlineBigCaller, \ + "can't inline: big caller") \ + _(CantInlineBigCallee, \ + "can't inline: big callee") \ + _(CantInlineNotHot, \ + "can't inline: not hot enough") \ + _(CantInlineNotInDispatch, \ + "can't inline: not in dispatch table") \ + _(CantInlineNativeBadForm, \ + "can't inline native: bad form (arity mismatch/constructing)") \ + _(CantInlineNativeBadType, \ + "can't inline native: bad argument or return type observed") \ + _(CantInlineNativeNoTemplateObj, \ + "can't inline native: no template object") \ + _(CantInlineBound, \ + "can't inline bound function invocation") \ + \ + _(GenericSuccess, \ + "success") \ + _(Inlined, \ + "inlined") \ + _(DOM, \ + "DOM") \ + _(Monomorphic, \ + "monomorphic") \ + _(Polymorphic, \ + "polymorphic") + +#define TRACKED_TYPESITE_LIST(_) \ + _(Receiver, \ + "receiver object") \ + _(Index, \ + "index") \ + _(Value, \ + "value") \ + _(Call_Target, \ + "call target") \ + _(Call_This, \ + "call 'this'") \ + _(Call_Arg, \ + "call argument") \ + _(Call_Return, \ + "call return") + +enum class TrackedStrategy : uint32_t { +#define STRATEGY_OP(name, msg) name, + TRACKED_STRATEGY_LIST(STRATEGY_OP) +#undef STRATEGY_OPT + + Count +}; + +enum class TrackedOutcome : uint32_t { +#define OUTCOME_OP(name, msg) name, + TRACKED_OUTCOME_LIST(OUTCOME_OP) +#undef OUTCOME_OP + + Count +}; + +enum class TrackedTypeSite : uint32_t { +#define TYPESITE_OP(name, msg) name, + TRACKED_TYPESITE_LIST(TYPESITE_OP) +#undef TYPESITE_OP + + Count +}; + +extern JS_PUBLIC_API(const char *) +TrackedStrategyString(TrackedStrategy strategy); + +extern JS_PUBLIC_API(const char *) +TrackedOutcomeString(TrackedOutcome outcome); + +extern JS_PUBLIC_API(const char *) +TrackedTypeSiteString(TrackedTypeSite site); + +struct ForEachTrackedOptimizationAttemptOp +{ + virtual void operator()(TrackedStrategy strategy, TrackedOutcome outcome) = 0; +}; + +JS_PUBLIC_API(void) +ForEachTrackedOptimizationAttempt(JSRuntime *rt, void *addr, uint8_t index, + ForEachTrackedOptimizationAttemptOp &op); + +struct ForEachTrackedOptimizationTypeInfoOp +{ + // Called 0+ times per entry, once for each type in the type set that Ion + // saw during MIR construction. readType is always called _before_ + // operator() on the same entry. + // + // The keyedBy parameter describes how the type is keyed: + // - "primitive" for primitive types + // - "constructor" for object types tied to a scripted constructor + // function. + // - "alloc site" for object types tied to an allocation site. + // - "prototype" for object types tied neither to a constructor nor + // to an allocation site. + // + // The name parameter is the string representation of the type. If the + // type is keyed by "constructor", or if the type itself refers to a + // scripted function, the name is the function's displayAtom. + // + // If the type is keyed by "constructor", "alloc site", or if the type + // itself refers to a scripted function, the location and lineno + // parameters will be respectively non-nullptr and non-0. + virtual void readType(const char *keyedBy, const char *name, + const char *location, unsigned lineno) = 0; + + // Called once per entry. + virtual void operator()(TrackedTypeSite site, const char *mirType) = 0; +}; + +extern JS_PUBLIC_API(void) +ForEachTrackedOptimizationTypeInfo(JSRuntime *rt, void *addr, uint8_t index, + ForEachTrackedOptimizationTypeInfoOp &op); + +} // namespace JS + +#endif // js_TrackedOptimizationInfo_h diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index 59bb89a62236..42e9bdd6a4c4 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -7328,7 +7328,7 @@ CodeGenerator::link(JSContext *cx, types::CompilerConstraintList *constraints) // Generate the tracked optimizations map. if (isOptimizationTrackingEnabled()) { // Treat OOMs and failures as if optimization tracking were turned off. - types::TypeSet::TypeList *allTypes = cx->new_(); + IonTrackedTypeVector *allTypes = cx->new_(); if (allTypes && generateCompactTrackedOptimizationsMap(cx, code, allTypes)) { const uint8_t *optsRegionTableAddr = trackedOptimizationsMap_ + trackedOptimizationsRegionTableOffset_; diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index c1267ee98947..0e8a28dbcc90 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -38,6 +38,10 @@ using mozilla::AssertedCast; using mozilla::DebugOnly; using mozilla::Maybe; +using JS::TrackedStrategy; +using JS::TrackedOutcome; +using JS::TrackedTypeSite; + class jit::BaselineFrameInspector { public: diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index 12affe120c04..8ef0d0658b28 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -1116,13 +1116,13 @@ class IonBuilder // The track* methods below are called often. Do not combine them with the // unchecked variants, despite the unchecked variants having no other // callers. - void trackTypeInfo(TrackedTypeSite site, MIRType mirType, + void trackTypeInfo(JS::TrackedTypeSite site, MIRType mirType, types::TemporaryTypeSet *typeSet) { if (MOZ_UNLIKELY(current->trackedSite()->hasOptimizations())) trackTypeInfoUnchecked(site, mirType, typeSet); } - void trackTypeInfo(TrackedTypeSite site, JSObject *obj) { + void trackTypeInfo(JS::TrackedTypeSite site, JSObject *obj) { if (MOZ_UNLIKELY(current->trackedSite()->hasOptimizations())) trackTypeInfoUnchecked(site, obj); } @@ -1130,7 +1130,7 @@ class IonBuilder if (MOZ_UNLIKELY(current->trackedSite()->hasOptimizations())) trackTypeInfoUnchecked(callInfo); } - void trackOptimizationAttempt(TrackedStrategy strategy) { + void trackOptimizationAttempt(JS::TrackedStrategy strategy) { if (MOZ_UNLIKELY(current->trackedSite()->hasOptimizations())) trackOptimizationAttemptUnchecked(strategy); } @@ -1138,7 +1138,7 @@ class IonBuilder if (MOZ_UNLIKELY(current->trackedSite()->hasOptimizations())) amendOptimizationAttemptUnchecked(index); } - void trackOptimizationOutcome(TrackedOutcome outcome) { + void trackOptimizationOutcome(JS::TrackedOutcome outcome) { if (MOZ_UNLIKELY(current->trackedSite()->hasOptimizations())) trackOptimizationOutcomeUnchecked(outcome); } @@ -1153,13 +1153,13 @@ class IonBuilder // Out-of-line variants that don't check if optimization tracking is // enabled. - void trackTypeInfoUnchecked(TrackedTypeSite site, MIRType mirType, + void trackTypeInfoUnchecked(JS::TrackedTypeSite site, MIRType mirType, types::TemporaryTypeSet *typeSet); - void trackTypeInfoUnchecked(TrackedTypeSite site, JSObject *obj); + void trackTypeInfoUnchecked(JS::TrackedTypeSite site, JSObject *obj); void trackTypeInfoUnchecked(CallInfo &callInfo); - void trackOptimizationAttemptUnchecked(TrackedStrategy strategy); + void trackOptimizationAttemptUnchecked(JS::TrackedStrategy strategy); void amendOptimizationAttemptUnchecked(uint32_t index); - void trackOptimizationOutcomeUnchecked(TrackedOutcome outcome); + void trackOptimizationOutcomeUnchecked(JS::TrackedOutcome outcome); void trackOptimizationSuccessUnchecked(); void trackInlineSuccessUnchecked(InliningStatus status); }; diff --git a/js/src/jit/JitcodeMap.h b/js/src/jit/JitcodeMap.h index 018e76f2dd12..96ebc3e62708 100644 --- a/js/src/jit/JitcodeMap.h +++ b/js/src/jit/JitcodeMap.h @@ -115,14 +115,14 @@ class JitcodeGlobalEntry // attempts vectors. // // All pointers point into the same block of memory; the beginning of - // the block is optimizationRegionTable_->payloadStart(). + // the block is optRegionTable_->payloadStart(). const IonTrackedOptimizationsRegionTable *optsRegionTable_; const IonTrackedOptimizationsTypesTable *optsTypesTable_; const IonTrackedOptimizationsAttemptsTable *optsAttemptsTable_; // The types table above records type sets, which have been gathered // into one vector here. - types::TypeSet::TypeList *optsAllTypes_; + IonTrackedTypeVector *optsAllTypes_; struct ScriptNamePair { JSScript *script; @@ -163,7 +163,7 @@ class JitcodeGlobalEntry void initTrackedOptimizations(const IonTrackedOptimizationsRegionTable *regionTable, const IonTrackedOptimizationsTypesTable *typesTable, const IonTrackedOptimizationsAttemptsTable *attemptsTable, - types::TypeSet::TypeList *allTypes) + IonTrackedTypeVector *allTypes) { optsRegionTable_ = regionTable; optsTypesTable_ = typesTable; @@ -214,7 +214,22 @@ class JitcodeGlobalEntry return !!optsRegionTable_; } - bool optimizationAttemptsAtAddr(void *ptr, mozilla::Maybe &attempts); + IonTrackedOptimizationsAttempts trackedOptimizationAttempts(uint8_t index) { + MOZ_ASSERT(hasTrackedOptimizations()); + return optsAttemptsTable_->entry(index); + } + + IonTrackedOptimizationsTypeInfo trackedOptimizationTypeInfo(uint8_t index) { + MOZ_ASSERT(hasTrackedOptimizations()); + return optsTypesTable_->entry(index); + } + + const IonTrackedTypeVector *allTrackedTypes() { + MOZ_ASSERT(hasTrackedOptimizations()); + return optsAllTypes_; + } + + mozilla::Maybe trackedOptimizationIndexAtAddr(void *ptr); }; struct BaselineEntry : public BaseEntry @@ -545,6 +560,46 @@ class JitcodeGlobalEntry // Compute a profiling string for a given script. static char *createScriptString(JSContext *cx, JSScript *script, size_t *length=nullptr); + + bool hasTrackedOptimizations() const { + switch (kind()) { + case Ion: + return ionEntry().hasTrackedOptimizations(); + case Baseline: + case IonCache: + case Dummy: + break; + default: + MOZ_CRASH("Invalid JitcodeGlobalEntry kind."); + } + return false; + } + + mozilla::Maybe trackedOptimizationIndexAtAddr(void *addr) { + switch (kind()) { + case Ion: + return ionEntry().trackedOptimizationIndexAtAddr(addr); + case Baseline: + case IonCache: + case Dummy: + break; + default: + MOZ_CRASH("Invalid JitcodeGlobalEntry kind."); + } + return mozilla::Nothing(); + } + + IonTrackedOptimizationsAttempts trackedOptimizationAttempts(uint8_t index) { + return ionEntry().trackedOptimizationAttempts(index); + } + + IonTrackedOptimizationsTypeInfo trackedOptimizationTypeInfo(uint8_t index) { + return ionEntry().trackedOptimizationTypeInfo(index); + } + + const IonTrackedTypeVector *allTrackedTypes() { + return ionEntry().allTrackedTypes(); + } }; /* diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index 19f57caa1b4e..8f44052c567c 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -24,6 +24,10 @@ using mozilla::ArrayLength; +using JS::TrackedStrategy; +using JS::TrackedOutcome; +using JS::TrackedTypeSite; + namespace js { namespace jit { diff --git a/js/src/jit/OptimizationTracking.cpp b/js/src/jit/OptimizationTracking.cpp index a416dabb0e66..7cfa5d551d9b 100644 --- a/js/src/jit/OptimizationTracking.cpp +++ b/js/src/jit/OptimizationTracking.cpp @@ -10,6 +10,7 @@ #include "jit/IonBuilder.h" #include "jit/JitcodeMap.h" #include "jit/JitSpewer.h" +#include "js/TrackedOptimizationInfo.h" using namespace js; using namespace js::jit; @@ -18,10 +19,14 @@ using mozilla::Maybe; using mozilla::Some; using mozilla::Nothing; -typedef CodeGeneratorShared::NativeToTrackedOptimizations NativeToTrackedOptimizations; +using JS::TrackedStrategy; +using JS::TrackedOutcome; +using JS::TrackedTypeSite; +using JS::ForEachTrackedOptimizationAttemptOp; +using JS::ForEachTrackedOptimizationTypeInfoOp; bool -TrackedOptimizations::trackTypeInfo(TrackedTypeInfo &&ty) +TrackedOptimizations::trackTypeInfo(OptimizationTypeInfo &&ty) { return types_.append(mozilla::Move(ty)); } @@ -67,20 +72,19 @@ VectorContentsMatch(const Vec *xs, const Vec *ys) } bool -TrackedOptimizations::matchTypes(const TempTrackedTypeInfoVector &other) const +TrackedOptimizations::matchTypes(const TempOptimizationTypeInfoVector &other) const { return VectorContentsMatch(&types_, &other); } bool -TrackedOptimizations::matchAttempts(const TempAttemptsVector &other) const +TrackedOptimizations::matchAttempts(const TempOptimizationAttemptsVector &other) const { return VectorContentsMatch(&attempts_, &other); } -#ifdef DEBUG -static const char * -StrategyString(TrackedStrategy strategy) +JS_PUBLIC_API(const char *) +JS::TrackedStrategyString(TrackedStrategy strategy) { switch (strategy) { #define STRATEGY_CASE(name, msg) \ @@ -94,8 +98,8 @@ StrategyString(TrackedStrategy strategy) } } -static const char * -OutcomeString(TrackedOutcome outcome) +JS_PUBLIC_API(const char *) +JS::TrackedOutcomeString(TrackedOutcome outcome) { switch (outcome) { #define OUTCOME_CASE(name, msg) \ @@ -109,10 +113,10 @@ OutcomeString(TrackedOutcome outcome) } } -static const char * -TypeSiteString(TrackedTypeSite kind) +JS_PUBLIC_API(const char *) +JS::TrackedTypeSiteString(TrackedTypeSite site) { - switch (kind) { + switch (site) { #define TYPESITE_CASE(name, msg) \ case TrackedTypeSite::name: \ return msg; @@ -123,15 +127,16 @@ TypeSiteString(TrackedTypeSite kind) MOZ_CRASH("bad type site"); } } -#endif // DEBUG void -SpewTempTrackedTypeInfoVector(const TempTrackedTypeInfoVector *types, const char *indent = nullptr) +SpewTempOptimizationTypeInfoVector(const TempOptimizationTypeInfoVector *types, + const char *indent = nullptr) { #ifdef DEBUG - for (const TrackedTypeInfo *t = types->begin(); t != types->end(); t++) { - JitSpewStart(JitSpew_OptimizationTracking, " %s%s of type %s, type set", indent ? indent : "", - TypeSiteString(t->site()), StringFromMIRType(t->mirType())); + for (const OptimizationTypeInfo *t = types->begin(); t != types->end(); t++) { + JitSpewStart(JitSpew_OptimizationTracking, " %s%s of type %s, type set", + indent ? indent : "", + TrackedTypeSiteString(t->site()), StringFromMIRType(t->mirType())); for (uint32_t i = 0; i < t->types().length(); i++) JitSpewCont(JitSpew_OptimizationTracking, " %s", types::TypeString(t->types()[i])); JitSpewFin(JitSpew_OptimizationTracking); @@ -140,12 +145,13 @@ SpewTempTrackedTypeInfoVector(const TempTrackedTypeInfoVector *types, const char } void -SpewTempAttemptsVector(const TempAttemptsVector *attempts, const char *indent = nullptr) +SpewTempOptimizationAttemptsVector(const TempOptimizationAttemptsVector *attempts, + const char *indent = nullptr) { #ifdef DEBUG for (const OptimizationAttempt *a = attempts->begin(); a != attempts->end(); a++) { JitSpew(JitSpew_OptimizationTracking, " %s%s: %s", indent ? indent : "", - StrategyString(a->strategy()), OutcomeString(a->outcome())); + TrackedStrategyString(a->strategy()), TrackedOutcomeString(a->outcome())); } #endif } @@ -154,13 +160,13 @@ void TrackedOptimizations::spew() const { #ifdef DEBUG - SpewTempTrackedTypeInfoVector(&types_); - SpewTempAttemptsVector(&attempts_); + SpewTempOptimizationTypeInfoVector(&types_); + SpewTempOptimizationAttemptsVector(&attempts_); #endif } bool -TrackedTypeInfo::trackTypeSet(types::TemporaryTypeSet *typeSet) +OptimizationTypeInfo::trackTypeSet(types::TemporaryTypeSet *typeSet) { if (!typeSet) return true; @@ -168,20 +174,20 @@ TrackedTypeInfo::trackTypeSet(types::TemporaryTypeSet *typeSet) } bool -TrackedTypeInfo::trackType(types::Type type) +OptimizationTypeInfo::trackType(types::Type type) { return types_.append(type); } bool -TrackedTypeInfo::operator ==(const TrackedTypeInfo &other) const +OptimizationTypeInfo::operator ==(const OptimizationTypeInfo &other) const { return site_ == other.site_ && mirType_ == other.mirType_ && VectorContentsMatch(&types_, &other.types_); } bool -TrackedTypeInfo::operator !=(const TrackedTypeInfo &other) const +OptimizationTypeInfo::operator !=(const OptimizationTypeInfo &other) const { return !(*this == other); } @@ -213,7 +219,7 @@ HashTypeList(const types::TypeSet::TypeList &types) } HashNumber -TrackedTypeInfo::hash() const +OptimizationTypeInfo::hash() const { return ((HashNumber(site_) << 24) + (HashNumber(mirType_) << 16)) ^ HashTypeList(types_); } @@ -434,28 +440,54 @@ IonTrackedOptimizationsRegion::RangeIterator::readNext(uint32_t *startOffset, ui MOZ_ASSERT(cur_ <= end_); } -bool -JitcodeGlobalEntry::IonEntry::optimizationAttemptsAtAddr(void *ptr, - Maybe &attempts) +Maybe +JitcodeGlobalEntry::IonEntry::trackedOptimizationIndexAtAddr(void *ptr) { - MOZ_ASSERT(!attempts); + MOZ_ASSERT(hasTrackedOptimizations()); MOZ_ASSERT(containsPointer(ptr)); uint32_t ptrOffset = ((uint8_t *) ptr) - ((uint8_t *) nativeStartAddr()); Maybe region = optsRegionTable_->findRegion(ptrOffset); if (region.isNothing()) - return true; - Maybe attemptsIdx = region->findAttemptsIndex(ptrOffset); - if (attemptsIdx.isNothing()) - return true; - IonTrackedOptimizationsAttempts attemptsEntry = optsAttemptsTable_->entry(*attemptsIdx); - attempts.emplace(); - if (!attemptsEntry.readVector(attempts.ptr())) - return false; - return true; + return Nothing(); + return region->findIndex(ptrOffset); +} + +void +IonTrackedOptimizationsAttempts::forEach(ForEachTrackedOptimizationAttemptOp &op) +{ + CompactBufferReader reader(start_, end_); + const uint8_t *cur = start_; + while (cur != end_) { + TrackedStrategy strategy = TrackedStrategy(reader.readUnsigned()); + TrackedOutcome outcome = TrackedOutcome(reader.readUnsigned()); + MOZ_ASSERT(strategy < TrackedStrategy::Count); + MOZ_ASSERT(outcome < TrackedOutcome::Count); + op(strategy, outcome); + cur = reader.currentPosition(); + MOZ_ASSERT(cur <= end_); + } +} + +void +IonTrackedOptimizationsTypeInfo::forEach(ForEachOp &op, const IonTrackedTypeVector *allTypes) +{ + CompactBufferReader reader(start_, end_); + const uint8_t *cur = start_; + while (cur != end_) { + TrackedTypeSite site = JS::TrackedTypeSite(reader.readUnsigned()); + MOZ_ASSERT(site < JS::TrackedTypeSite::Count); + MIRType mirType = MIRType(reader.readUnsigned()); + uint32_t length = reader.readUnsigned(); + for (uint32_t i = 0; i < length; i++) + op.readType((*allTypes)[reader.readByte()]); + op(site, mirType); + cur = reader.currentPosition(); + MOZ_ASSERT(cur <= end_); + } } Maybe -IonTrackedOptimizationsRegion::findAttemptsIndex(uint32_t offset) const +IonTrackedOptimizationsRegion::findIndex(uint32_t offset) const { if (offset < startOffset_ || offset >= endOffset_) return Nothing(); @@ -555,7 +587,7 @@ OptimizationAttempt::writeCompact(CompactBufferWriter &writer) const } bool -TrackedTypeInfo::writeCompact(CompactBufferWriter &writer, +OptimizationTypeInfo::writeCompact(CompactBufferWriter &writer, UniqueTrackedTypes &uniqueTypes) const { writer.writeUnsigned((uint32_t) site_); @@ -747,32 +779,6 @@ IonTrackedOptimizationsRegion::WriteRun(CompactBufferWriter &writer, return true; } -TrackedTypeInfo::TrackedTypeInfo(CompactBufferReader &reader) - : site_(TrackedTypeSite(reader.readUnsigned())), - mirType_(MIRType(reader.readUnsigned())) -{ - MOZ_ASSERT(site_ < TrackedTypeSite::Count); -} - -bool -TrackedTypeInfo::readTypes(CompactBufferReader &reader, const types::TypeSet::TypeList *allTypes) -{ - uint32_t length = reader.readUnsigned(); - for (uint32_t i = 0; i < length; i++) { - if (!types_.append((*allTypes)[reader.readByte()])) - return false; - } - return true; -} - -OptimizationAttempt::OptimizationAttempt(CompactBufferReader &reader) - : strategy_(TrackedStrategy(reader.readUnsigned())), - outcome_(TrackedOutcome(reader.readUnsigned())) -{ - MOZ_ASSERT(strategy_ < TrackedStrategy::Count); - MOZ_ASSERT(outcome_ < TrackedOutcome::Count); -} - static bool WriteOffsetsTable(CompactBufferWriter &writer, const Vector &offsets, uint32_t *tableOffsetp) @@ -807,6 +813,50 @@ WriteOffsetsTable(CompactBufferWriter &writer, const Vector &offse return true; } +static JSFunction * +MaybeConstructorFromType(types::Type ty) +{ + if (ty.isUnknown() || ty.isAnyObject() || !ty.isGroup()) + return nullptr; + types::ObjectGroup *obj = ty.group(); + types::TypeNewScript *newScript = obj->newScript(); + if (!newScript && obj->maybeUnboxedLayout()) + newScript = obj->unboxedLayout().newScript(); + return newScript ? newScript->function() : nullptr; +} + +static void +SpewConstructor(types::Type ty, JSFunction *constructor) +{ +#ifdef DEBUG + char buf[512]; + PutEscapedString(buf, 512, constructor->displayAtom(), 0); + + const char *filename; + uint32_t lineno; + if (constructor->hasScript()) { + filename = constructor->nonLazyScript()->filename(); + lineno = constructor->nonLazyScript()->lineno(); + } else { + filename = constructor->lazyScript()->filename(); + lineno = constructor->lazyScript()->lineno(); + } + + JitSpew(JitSpew_OptimizationTracking, " Unique type %s has constructor %s (%s:%u)", + types::TypeString(ty), buf, filename, lineno); +#endif +} + +static void +SpewAllocationSite(types::Type ty, JSScript *script, uint32_t offset) +{ +#ifdef DEBUG + JitSpew(JitSpew_OptimizationTracking, " Unique type %s has alloc site %s:%u", + types::TypeString(ty), script->filename(), + PCToLineNumber(script, script->offsetToPC(offset))); +#endif +} + bool jit::WriteIonTrackedOptimizationsTable(JSContext *cx, CompactBufferWriter &writer, const NativeToTrackedOptimizations *start, @@ -816,7 +866,7 @@ jit::WriteIonTrackedOptimizationsTable(JSContext *cx, CompactBufferWriter &write uint32_t *regionTableOffsetp, uint32_t *typesTableOffsetp, uint32_t *optimizationTableOffsetp, - types::TypeSet::TypeList *allTypes) + IonTrackedTypeVector *allTypes) { MOZ_ASSERT(unique.sorted()); @@ -873,23 +923,47 @@ jit::WriteIonTrackedOptimizationsTable(JSContext *cx, CompactBufferWriter &write return false; for (const UniqueTrackedOptimizations::SortEntry *p = vec.begin(); p != vec.end(); p++) { - const TempTrackedTypeInfoVector *v = p->types; + const TempOptimizationTypeInfoVector *v = p->types; JitSpew(JitSpew_OptimizationTracking, " Type info entry %u of length %u, offset %u", p - vec.begin(), v->length(), writer.length()); - SpewTempTrackedTypeInfoVector(v, " "); + SpewTempOptimizationTypeInfoVector(v, " "); if (!offsets.append(writer.length())) return false; - for (const TrackedTypeInfo *t = v->begin(); t != v->end(); t++) { + for (const OptimizationTypeInfo *t = v->begin(); t != v->end(); t++) { if (!t->writeCompact(writer, uniqueTypes)) return false; } } - // Copy the unique type list into the outparam TypeList. - if (!uniqueTypes.enumerate(allTypes)) + // Enumerate the unique types, and pull out any 'new' script constructor + // functions and allocation site information. We do this during linking + // instead of during profiling to avoid touching compartment tables during + // profiling. Additionally, TypeNewScript is subject to GC in the + // meantime. + types::TypeSet::TypeList uniqueTypeList; + if (!uniqueTypes.enumerate(&uniqueTypeList)) return false; + for (uint32_t i = 0; i < uniqueTypeList.length(); i++) { + types::Type ty = uniqueTypeList[i]; + if (JSFunction *constructor = MaybeConstructorFromType(ty)) { + if (!allTypes->append(IonTrackedTypeWithAddendum(ty, constructor))) + return false; + SpewConstructor(ty, constructor); + } else { + JSScript *script; + uint32_t offset; + if (cx->findAllocationSiteForType(ty, &script, &offset)) { + if (!allTypes->append(IonTrackedTypeWithAddendum(ty, script, offset))) + return false; + SpewAllocationSite(ty, script, offset); + } else { + if (!allTypes->append(IonTrackedTypeWithAddendum(ty))) + return false; + } + } + } if (!WriteOffsetsTable(writer, offsets, typesTableOffsetp)) return false; @@ -897,10 +971,10 @@ jit::WriteIonTrackedOptimizationsTable(JSContext *cx, CompactBufferWriter &write // Write out attempts payloads. for (const UniqueTrackedOptimizations::SortEntry *p = vec.begin(); p != vec.end(); p++) { - const TempAttemptsVector *v = p->attempts; + const TempOptimizationAttemptsVector *v = p->attempts; JitSpew(JitSpew_OptimizationTracking, " Attempts entry %u of length %u, offset %u", p - vec.begin(), v->length(), writer.length()); - SpewTempAttemptsVector(v, " "); + SpewTempOptimizationAttemptsVector(v, " "); if (!offsets.append(writer.length())) return false; @@ -962,7 +1036,7 @@ IonBuilder::trackTypeInfoUnchecked(TrackedTypeSite kind, MIRType mirType, { BytecodeSite *site = current->trackedSite(); // OOMs are handled as if optimization tracking were turned off. - TrackedTypeInfo typeInfo(kind, mirType); + OptimizationTypeInfo typeInfo(kind, mirType); if (!typeInfo.trackTypeSet(typeSet)) { site->setOptimizations(nullptr); return; @@ -976,7 +1050,7 @@ IonBuilder::trackTypeInfoUnchecked(TrackedTypeSite kind, JSObject *obj) { BytecodeSite *site = current->trackedSite(); // OOMs are handled as if optimization tracking were turned off. - TrackedTypeInfo typeInfo(kind, MIRType_Object); + OptimizationTypeInfo typeInfo(kind, MIRType_Object); if (!typeInfo.trackType(types::Type::ObjectType(obj))) return; if (!site->optimizations()->trackTypeInfo(mozilla::Move(typeInfo))) @@ -1035,3 +1109,104 @@ IonBuilder::trackInlineSuccessUnchecked(InliningStatus status) if (status == InliningStatus_Inlined) trackOptimizationOutcome(TrackedOutcome::Inlined); } + +JS_PUBLIC_API(void) +JS::ForEachTrackedOptimizationAttempt(JSRuntime *rt, void *addr, uint8_t index, + ForEachTrackedOptimizationAttemptOp &op) +{ + JitcodeGlobalTable *table = rt->jitRuntime()->getJitcodeGlobalTable(); + JitcodeGlobalEntry entry; + table->lookupInfallible(addr, &entry, rt); + entry.trackedOptimizationAttempts(index).forEach(op); +} + +static void +InterpretedFunctionFilenameAndLineNumber(JSFunction *fun, const char **filename, unsigned *lineno) +{ + ScriptSource *source; + if (fun->hasScript()) { + source = fun->nonLazyScript()->maybeForwardedScriptSource(); + *lineno = fun->nonLazyScript()->lineno(); + } else { + source = fun->lazyScript()->maybeForwardedScriptSource(); + *lineno = fun->lazyScript()->lineno(); + } + *filename = source->introducerFilename(); +} + +static JSFunction * +InterpretedFunctionFromTrackedType(const IonTrackedTypeWithAddendum &tracked) +{ + if (tracked.hasConstructor()) + return tracked.constructor; + + types::Type ty = tracked.type; + + if (ty.isSingleton()) { + JSObject *obj = ty.singleton(); + return obj->is() ? &obj->as() : nullptr; + } + + return ty.group()->maybeInterpretedFunction(); +} + +// This adapter is needed as the internal API can deal with engine-internal +// data structures directly, while the public API cannot. +class ForEachTypeInfoAdapter : public IonTrackedOptimizationsTypeInfo::ForEachOp +{ + ForEachTrackedOptimizationTypeInfoOp &op_; + + public: + explicit ForEachTypeInfoAdapter(ForEachTrackedOptimizationTypeInfoOp &op) + : op_(op) + { } + + void readType(const IonTrackedTypeWithAddendum &tracked) MOZ_OVERRIDE { + types::Type ty = tracked.type; + + if (ty.isPrimitive() || ty.isUnknown() || ty.isAnyObject()) { + op_.readType("primitive", types::NonObjectTypeString(ty), nullptr, 0); + return; + } + + char buf[512]; + const uint32_t bufsize = mozilla::ArrayLength(buf); + + if (JSFunction *fun = InterpretedFunctionFromTrackedType(tracked)) { + PutEscapedString(buf, bufsize, fun->displayAtom(), 0); + const char *filename; + unsigned lineno; + InterpretedFunctionFilenameAndLineNumber(fun, &filename, &lineno); + op_.readType(tracked.constructor ? "constructor" : "function", buf, filename, lineno); + return; + } + + const char *className = ty.objectKey()->clasp()->name; + JS_snprintf(buf, bufsize, "[object %s]", className); + + if (tracked.hasAllocationSite()) { + JSScript *script = tracked.script; + op_.readType("alloc site", buf, + script->maybeForwardedScriptSource()->introducerFilename(), + PCToLineNumber(script, script->offsetToPC(tracked.offset))); + return; + } + + op_.readType("prototype", buf, nullptr, 0); + } + + void operator()(JS::TrackedTypeSite site, MIRType mirType) MOZ_OVERRIDE { + op_(site, StringFromMIRType(mirType)); + } +}; + +JS_PUBLIC_API(void) +JS::ForEachTrackedOptimizationTypeInfo(JSRuntime *rt, void *addr, uint8_t index, + ForEachTrackedOptimizationTypeInfoOp &op) +{ + JitcodeGlobalTable *table = rt->jitRuntime()->getJitcodeGlobalTable(); + JitcodeGlobalEntry entry; + table->lookupInfallible(addr, &entry, rt); + ForEachTypeInfoAdapter adapter(op); + entry.trackedOptimizationTypeInfo(index).forEach(adapter, entry.allTrackedTypes()); +} diff --git a/js/src/jit/OptimizationTracking.h b/js/src/jit/OptimizationTracking.h index 0a31f55b54eb..2876dfa1a3ec 100644 --- a/js/src/jit/OptimizationTracking.h +++ b/js/src/jit/OptimizationTracking.h @@ -13,280 +13,30 @@ #include "jit/CompactBuffer.h" #include "jit/CompileInfo.h" #include "jit/JitAllocPolicy.h" -#include "jit/shared/CodeGenerator-shared.h" +#include "js/TrackedOptimizationInfo.h" namespace js { namespace jit { -#define TRACKED_STRATEGY_LIST(_) \ - _(GetProp_ArgumentsLength, \ - "getprop arguments.length") \ - _(GetProp_ArgumentsCallee, \ - "getprop arguments.callee") \ - _(GetProp_InferredConstant, \ - "getprop inferred constant") \ - _(GetProp_Constant, \ - "getprop constant") \ - _(GetProp_TypedObject, \ - "getprop TypedObject") \ - _(GetProp_DefiniteSlot, \ - "getprop definite slot") \ - _(GetProp_Unboxed, \ - "getprop unboxed object") \ - _(GetProp_CommonGetter, \ - "getprop common getter") \ - _(GetProp_InlineAccess, \ - "getprop inline access") \ - _(GetProp_Innerize, \ - "getprop innerize (access on global window)") \ - _(GetProp_InlineCache, \ - "getprop IC") \ - \ - _(SetProp_CommonSetter, \ - "setprop common setter") \ - _(SetProp_TypedObject, \ - "setprop TypedObject") \ - _(SetProp_DefiniteSlot, \ - "setprop definite slot") \ - _(SetProp_Unboxed, \ - "setprop unboxed object") \ - _(SetProp_InlineAccess, \ - "setprop inline access") \ - \ - _(GetElem_TypedObject, \ - "getprop TypedObject") \ - _(GetElem_Dense, \ - "getelem dense") \ - _(GetElem_TypedStatic, \ - "getelem TypedArray static") \ - _(GetElem_TypedArray, \ - "getelem TypedArray") \ - _(GetElem_String, \ - "getelem string") \ - _(GetElem_Arguments, \ - "getelem arguments") \ - _(GetElem_ArgumentsInlined, \ - "getelem arguments inlined") \ - _(GetElem_InlineCache, \ - "getelem IC") \ - \ - _(SetElem_TypedObject, \ - "setelem TypedObject") \ - _(SetElem_TypedStatic, \ - "setelem TypedArray static") \ - _(SetElem_TypedArray, \ - "setelem TypedArray") \ - _(SetElem_Dense, \ - "setelem dense") \ - _(SetElem_Arguments, \ - "setelem arguments") \ - _(SetElem_InlineCache, \ - "setelem IC") \ - \ - _(Call_Inline, \ - "call inline") - - -// Ordering is important below. All outcomes before GenericSuccess will be -// considered failures, and all outcomes after GenericSuccess will be -// considered successes. -#define TRACKED_OUTCOME_LIST(_) \ - _(GenericFailure, \ - "failure") \ - _(Disabled, \ - "disabled") \ - _(NoTypeInfo, \ - "no type info") \ - _(NoAnalysisInfo, \ - "no newscript analysis") \ - _(NoShapeInfo, \ - "cannot determine shape") \ - _(UnknownObject, \ - "unknown object") \ - _(UnknownProperties, \ - "unknown properties") \ - _(Singleton, \ - "is singleton") \ - _(NotSingleton, \ - "is not singleton") \ - _(NotFixedSlot, \ - "property not in fixed slot") \ - _(InconsistentFixedSlot, \ - "property not in a consistent fixed slot") \ - _(NotObject, \ - "not definitely an object") \ - _(NotStruct, \ - "not definitely a TypedObject struct") \ - _(NotUnboxed, \ - "not definitely an unboxed object") \ - _(StructNoField, \ - "struct doesn't definitely have field") \ - _(InconsistentFieldType, \ - "unboxed property does not consistent type") \ - _(InconsistentFieldOffset, \ - "unboxed property does not consistent offset") \ - _(NeedsTypeBarrier, \ - "needs type barrier") \ - _(InDictionaryMode, \ - "object in dictionary mode") \ - _(NoProtoFound, \ - "no proto found") \ - _(MultiProtoPaths, \ - "not all paths to property go through same proto") \ - _(NonWritableProperty, \ - "non-writable property") \ - _(ProtoIndexedProps, \ - "prototype has indexed properties") \ - _(ArrayBadFlags, \ - "array observed to be sparse, overflowed .length, or has been iterated") \ - _(ArrayDoubleConversion, \ - "array has ambiguous double conversion") \ - _(ArrayRange, \ - "array range issue (.length problems)") \ - _(ArraySeenNegativeIndex, \ - "has seen array access with negative index") \ - _(TypedObjectNeutered, \ - "TypedObject might have been neutered") \ - _(TypedObjectArrayRange, \ - "TypedObject array of unknown length") \ - _(AccessNotDense, \ - "access not on dense native (check receiver, index, and result types)") \ - _(AccessNotTypedObject, \ - "access not on typed array (check receiver and index types)") \ - _(AccessNotTypedArray, \ - "access not on typed array (check receiver, index, and result types)") \ - _(AccessNotString, \ - "getelem not on string (check receiver and index types)") \ - _(StaticTypedArrayUint32, \ - "static uint32 arrays currently cannot be optimized") \ - _(StaticTypedArrayCantComputeMask, \ - "can't compute mask for static typed array access (index isn't constant or not int32)") \ - _(OutOfBounds, \ - "observed out of bounds access") \ - _(GetElemStringNotCached, \ - "getelem on strings is not inline cached") \ - _(NonNativeReceiver, \ - "observed non-native receiver") \ - _(IndexType, \ - "index type must be int32, string, or symbol") \ - _(SetElemNonDenseNonTANotCached, \ - "setelem on non-dense non-TAs are not inline cached") \ - \ - _(CantInlineGeneric, \ - "can't inline") \ - _(CantInlineNoTarget, \ - "can't inline: no target") \ - _(CantInlineNotInterpreted, \ - "can't inline: not interpreted") \ - _(CantInlineNoBaseline, \ - "can't inline: no baseline code") \ - _(CantInlineLazy, \ - "can't inline: lazy script") \ - _(CantInlineNotConstructor, \ - "can't inline: calling non-constructor with 'new'") \ - _(CantInlineDisabledIon, \ - "can't inline: ion disabled for callee") \ - _(CantInlineTooManyArgs, \ - "can't inline: too many arguments") \ - _(CantInlineRecursive, \ - "can't inline: recursive") \ - _(CantInlineHeavyweight, \ - "can't inline: heavyweight") \ - _(CantInlineNeedsArgsObj, \ - "can't inline: needs arguments object") \ - _(CantInlineDebuggee, \ - "can't inline: debuggee") \ - _(CantInlineUnknownProps, \ - "can't inline: type has unknown properties") \ - _(CantInlineExceededDepth, \ - "can't inline: exceeded inlining depth") \ - _(CantInlineBigLoop, \ - "can't inline: big function with a loop") \ - _(CantInlineBigCaller, \ - "can't inline: big caller") \ - _(CantInlineBigCallee, \ - "can't inline: big callee") \ - _(CantInlineNotHot, \ - "can't inline: not hot enough") \ - _(CantInlineNotInDispatch, \ - "can't inline: not in dispatch table") \ - _(CantInlineNativeBadForm, \ - "can't inline native: bad form (arity mismatch/constructing)") \ - _(CantInlineNativeBadType, \ - "can't inline native: bad argument or return type observed") \ - _(CantInlineNativeNoTemplateObj, \ - "can't inline native: no template object") \ - _(CantInlineBound, \ - "can't inline bound function invocation") \ - \ - _(GenericSuccess, \ - "success") \ - _(Inlined, \ - "inlined") \ - _(DOM, \ - "DOM") \ - _(Monomorphic, \ - "monomorphic") \ - _(Polymorphic, \ - "polymorphic") - -#define TRACKED_TYPESITE_LIST(_) \ - _(Receiver, \ - "receiver object") \ - _(Index, \ - "index") \ - _(Value, \ - "value") \ - _(Call_Target, \ - "call target") \ - _(Call_This, \ - "call 'this'") \ - _(Call_Arg, \ - "call argument") \ - _(Call_Return, \ - "call return") - -enum class TrackedStrategy : uint32_t { -#define STRATEGY_OP(name, msg) name, - TRACKED_STRATEGY_LIST(STRATEGY_OP) -#undef STRATEGY_OPT - - Count -}; - -enum class TrackedOutcome : uint32_t { -#define OUTCOME_OP(name, msg) name, - TRACKED_OUTCOME_LIST(OUTCOME_OP) -#undef OUTCOME_OP - - Count -}; - -enum class TrackedTypeSite : uint32_t { -#define TYPESITE_OP(name, msg) name, - TRACKED_TYPESITE_LIST(TYPESITE_OP) -#undef TYPESITE_OP - - Count -}; +struct NativeToTrackedOptimizations; class OptimizationAttempt { - TrackedStrategy strategy_; - TrackedOutcome outcome_; + JS::TrackedStrategy strategy_; + JS::TrackedOutcome outcome_; public: - OptimizationAttempt(TrackedStrategy strategy, TrackedOutcome outcome) + OptimizationAttempt(JS::TrackedStrategy strategy, JS::TrackedOutcome outcome) : strategy_(strategy), outcome_(outcome) { } - void setOutcome(TrackedOutcome outcome) { outcome_ = outcome; } - bool succeeded() const { return outcome_ >= TrackedOutcome::GenericSuccess; } - bool failed() const { return outcome_ < TrackedOutcome::GenericSuccess; } - TrackedStrategy strategy() const { return strategy_; } - TrackedOutcome outcome() const { return outcome_; } + void setOutcome(JS::TrackedOutcome outcome) { outcome_ = outcome; } + bool succeeded() const { return outcome_ >= JS::TrackedOutcome::GenericSuccess; } + bool failed() const { return outcome_ < JS::TrackedOutcome::GenericSuccess; } + JS::TrackedStrategy strategy() const { return strategy_; } + JS::TrackedOutcome outcome() const { return outcome_; } bool operator ==(const OptimizationAttempt &other) const { return strategy_ == other.strategy_ && outcome_ == other.outcome_; @@ -298,29 +48,27 @@ class OptimizationAttempt return (HashNumber(strategy_) << 8) + HashNumber(outcome_); } - explicit OptimizationAttempt(CompactBufferReader &reader); void writeCompact(CompactBufferWriter &writer) const; }; -typedef Vector TempAttemptsVector; -typedef Vector AttemptsVector; +typedef Vector TempOptimizationAttemptsVector; class UniqueTrackedTypes; -class TrackedTypeInfo +class OptimizationTypeInfo { - TrackedTypeSite site_; + JS::TrackedTypeSite site_; MIRType mirType_; types::TypeSet::TypeList types_; public: - TrackedTypeInfo(TrackedTypeInfo &&other) + OptimizationTypeInfo(OptimizationTypeInfo &&other) : site_(other.site_), mirType_(other.mirType_), types_(mozilla::Move(other.types_)) { } - TrackedTypeInfo(TrackedTypeSite site, MIRType mirType) + OptimizationTypeInfo(JS::TrackedTypeSite site, MIRType mirType) : site_(site), mirType_(mirType) { } @@ -328,32 +76,26 @@ class TrackedTypeInfo bool trackTypeSet(types::TemporaryTypeSet *typeSet); bool trackType(types::Type type); - TrackedTypeSite site() const { return site_; } + JS::TrackedTypeSite site() const { return site_; } MIRType mirType() const { return mirType_; } const types::TypeSet::TypeList &types() const { return types_; } - bool operator ==(const TrackedTypeInfo &other) const; - bool operator !=(const TrackedTypeInfo &other) const; + bool operator ==(const OptimizationTypeInfo &other) const; + bool operator !=(const OptimizationTypeInfo &other) const; HashNumber hash() const; - // This constructor is designed to be used in conjunction with readTypes - // below it. The same reader must be passed to readTypes after - // instantiating the TrackedTypeInfo. - explicit TrackedTypeInfo(CompactBufferReader &reader); - bool readTypes(CompactBufferReader &reader, const types::TypeSet::TypeList *allTypes); bool writeCompact(CompactBufferWriter &writer, UniqueTrackedTypes &uniqueTypes) const; }; -typedef Vector TempTrackedTypeInfoVector; -typedef Vector TrackedTypeInfoVector; +typedef Vector TempOptimizationTypeInfoVector; // Tracks the optimization attempts made at a bytecode location. class TrackedOptimizations : public TempObject { friend class UniqueTrackedOptimizations; - TempTrackedTypeInfoVector types_; - TempAttemptsVector attempts_; + TempOptimizationTypeInfoVector types_; + TempOptimizationAttemptsVector attempts_; uint32_t currentAttempt_; public: @@ -363,15 +105,15 @@ class TrackedOptimizations : public TempObject currentAttempt_(UINT32_MAX) { } - bool trackTypeInfo(TrackedTypeInfo &&ty); + bool trackTypeInfo(OptimizationTypeInfo &&ty); - bool trackAttempt(TrackedStrategy strategy); + bool trackAttempt(JS::TrackedStrategy strategy); void amendAttempt(uint32_t index); - void trackOutcome(TrackedOutcome outcome); + void trackOutcome(JS::TrackedOutcome outcome); void trackSuccess(); - bool matchTypes(const TempTrackedTypeInfoVector &other) const; - bool matchAttempts(const TempAttemptsVector &other) const; + bool matchTypes(const TempOptimizationTypeInfoVector &other) const; + bool matchAttempts(const TempOptimizationAttemptsVector &other) const; void spew() const; }; @@ -383,8 +125,8 @@ class UniqueTrackedOptimizations public: struct SortEntry { - const TempTrackedTypeInfoVector *types; - const TempAttemptsVector *attempts; + const TempOptimizationTypeInfoVector *types; + const TempOptimizationAttemptsVector *attempts; uint32_t frequency; }; typedef Vector SortedVector; @@ -392,8 +134,8 @@ class UniqueTrackedOptimizations private: struct Key { - const TempTrackedTypeInfoVector *types; - const TempAttemptsVector *attempts; + const TempOptimizationTypeInfoVector *types; + const TempOptimizationAttemptsVector *attempts; typedef Key Lookup; static HashNumber hash(const Lookup &lookup); @@ -409,12 +151,12 @@ class UniqueTrackedOptimizations uint32_t frequency; }; - // Map of unique (TempTrackedTypeInfoVector, TempAttemptsVector) pairs to - // indices. + // Map of unique (TempOptimizationTypeInfoVector, + // TempOptimizationAttemptsVector) pairs to indices. typedef HashMap AttemptsMap; AttemptsMap map_; - // TempAttemptsVectors sorted by frequency. + // TempOptimizationAttemptsVectors sorted by frequency. SortedVector sorted_; public: @@ -457,7 +199,7 @@ class UniqueTrackedOptimizations // | Optimization type info 1 | | // |------------------------------------------------| | // | Optimization type info 2 | |-- PayloadT of list of -// |------------------------------------------------| | IonTrackedOptimizationTypeInfo in +// |------------------------------------------------| | OptimizationTypeInfo in // | ... | | order of decreasing frequency // |------------------------------------------------| | // | Optimization type info N | | @@ -475,7 +217,7 @@ class UniqueTrackedOptimizations // | Optimization attempts 1 | | // |------------------------------------------------| | // | Optimization attempts 2 | |-- PayloadA of list of -// |------------------------------------------------| | IonTrackedOptimizationAttempts in +// |------------------------------------------------| | OptimizationAttempts in // | ... | | order of decreasing frequency // |------------------------------------------------| | // | Optimization attempts N | | @@ -569,7 +311,9 @@ class IonTrackedOptimizationsRegion RangeIterator ranges() const { return RangeIterator(rangesStart_, end_, startOffset_); } - mozilla::Maybe findAttemptsIndex(uint32_t offset) const; + // Find the index of tracked optimization info (e.g., type info and + // attempts) at a native code offset. + mozilla::Maybe findIndex(uint32_t offset) const; // For the variants below, S stands for startDelta, L for length, and I // for index. These were automatically generated from training on the @@ -646,7 +390,6 @@ class IonTrackedOptimizationsRegion static const uint32_t MAX_RUN_LENGTH = 100; - typedef CodeGeneratorShared::NativeToTrackedOptimizations NativeToTrackedOptimizations; static uint32_t ExpectedRunLength(const NativeToTrackedOptimizations *start, const NativeToTrackedOptimizations *end); @@ -673,20 +416,55 @@ class IonTrackedOptimizationsAttempts MOZ_ASSERT(start < end); } - template - bool readVector(T *attempts) { - CompactBufferReader reader(start_, end_); - const uint8_t *cur = start_; - while (cur != end_) { - if (!attempts->append(OptimizationAttempt(reader))) - return false; - cur = reader.currentPosition(); - MOZ_ASSERT(cur <= end_); - } - return true; - } + void forEach(JS::ForEachTrackedOptimizationAttemptOp &op); }; +struct IonTrackedTypeWithAddendum +{ + types::Type type; + + enum HasAddendum { + HasNothing, + HasAllocationSite, + HasConstructor + }; + HasAddendum hasAddendum; + + // If type is a type object and is tied to a site, the script and pc are + // resolved early and stored below. This is done to avoid accessing the + // compartment during profiling time. + union { + struct { + JSScript *script; + uint32_t offset; + }; + JSFunction *constructor; + }; + + explicit IonTrackedTypeWithAddendum(types::Type type) + : type(type), + hasAddendum(HasNothing) + { } + + IonTrackedTypeWithAddendum(types::Type type, JSScript *script, uint32_t offset) + : type(type), + hasAddendum(HasAllocationSite), + script(script), + offset(offset) + { } + + IonTrackedTypeWithAddendum(types::Type type, JSFunction *constructor) + : type(type), + hasAddendum(HasConstructor), + constructor(constructor) + { } + + bool hasAllocationSite() const { return hasAddendum == HasAllocationSite; } + bool hasConstructor() const { return hasAddendum == HasConstructor; } +}; + +typedef Vector IonTrackedTypeVector; + class IonTrackedOptimizationsTypeInfo { const uint8_t *start_; @@ -701,21 +479,17 @@ class IonTrackedOptimizationsTypeInfo bool empty() const { return start_ == end_; } - template - bool readVector(T *types, const types::TypeSet::TypeList *allTypes) { - CompactBufferReader reader(start_, end_); - const uint8_t *cur = start_; - while (cur != end_) { - TrackedTypeInfo ty(reader); - if (!ty.readTypes(reader, allTypes)) - return false; - if (!types->append(mozilla::Move(ty))) - return false; - cur = reader.currentPosition(); - MOZ_ASSERT(cur <= end_); - } - return true; - } + // Unlike IonTrackedOptimizationAttempts, + // JS::ForEachTrackedOptimizaitonTypeInfoOp cannot be used directly. The + // internal API needs to deal with engine-internal data structures (e.g., + // types::Type) directly. + struct ForEachOp + { + virtual void readType(const IonTrackedTypeWithAddendum &tracked) = 0; + virtual void operator()(JS::TrackedTypeSite site, MIRType mirType) = 0; + }; + + void forEach(ForEachOp &op, const IonTrackedTypeVector *allTypes); }; template @@ -763,12 +537,12 @@ typedef IonTrackedOptimizationsOffsetsTable bool WriteIonTrackedOptimizationsTable(JSContext *cx, CompactBufferWriter &writer, - const CodeGeneratorShared::NativeToTrackedOptimizations *start, - const CodeGeneratorShared::NativeToTrackedOptimizations *end, + const NativeToTrackedOptimizations *start, + const NativeToTrackedOptimizations *end, const UniqueTrackedOptimizations &unique, uint32_t *numRegions, uint32_t *regionTableOffsetp, uint32_t *typesTableOffsetp, uint32_t *attemptsTableOffsetp, - types::TypeSet::TypeList *allTypes); + IonTrackedTypeVector *allTypes); } // namespace jit } // namespace js diff --git a/js/src/jit/shared/CodeGenerator-shared.cpp b/js/src/jit/shared/CodeGenerator-shared.cpp index b917e164ad58..4a19409e54c6 100644 --- a/js/src/jit/shared/CodeGenerator-shared.cpp +++ b/js/src/jit/shared/CodeGenerator-shared.cpp @@ -777,7 +777,7 @@ CodeGeneratorShared::verifyCompactNativeToBytecodeMap(JitCode *code) bool CodeGeneratorShared::generateCompactTrackedOptimizationsMap(JSContext *cx, JitCode *code, - types::TypeSet::TypeList *allTypes) + IonTrackedTypeVector *allTypes) { MOZ_ASSERT(trackedOptimizationsMap_ == nullptr); MOZ_ASSERT(trackedOptimizationsMapSize_ == 0); @@ -848,15 +848,57 @@ CodeGeneratorShared::generateCompactTrackedOptimizationsMap(JSContext *cx, JitCo data, data + trackedOptimizationsMapSize_, trackedOptimizationsMapSize_); JitSpew(JitSpew_OptimizationTracking, " with type list of length %u, size %u", - allTypes->length(), allTypes->length() * sizeof(types::Type)); + allTypes->length(), allTypes->length() * sizeof(IonTrackedTypeWithAddendum)); return true; } +#ifdef DEBUG +// Since this is a DEBUG-only verification, crash on OOM in the forEach ops +// below. + +class ReadTempAttemptsVectorOp : public JS::ForEachTrackedOptimizationAttemptOp +{ + TempOptimizationAttemptsVector *attempts_; + + public: + explicit ReadTempAttemptsVectorOp(TempOptimizationAttemptsVector *attempts) + : attempts_(attempts) + { } + + void operator()(JS::TrackedStrategy strategy, JS::TrackedOutcome outcome) MOZ_OVERRIDE { + MOZ_ALWAYS_TRUE(attempts_->append(OptimizationAttempt(strategy, outcome))); + } +}; + +struct ReadTempTypeInfoVectorOp : public IonTrackedOptimizationsTypeInfo::ForEachOp +{ + TempOptimizationTypeInfoVector *types_; + types::TypeSet::TypeList accTypes_; + + public: + explicit ReadTempTypeInfoVectorOp(TempOptimizationTypeInfoVector *types) + : types_(types) + { } + + void readType(const IonTrackedTypeWithAddendum &tracked) MOZ_OVERRIDE { + MOZ_ALWAYS_TRUE(accTypes_.append(tracked.type)); + } + + void operator()(JS::TrackedTypeSite site, MIRType mirType) MOZ_OVERRIDE { + OptimizationTypeInfo ty(site, mirType); + for (uint32_t i = 0; i < accTypes_.length(); i++) + MOZ_ALWAYS_TRUE(ty.trackType(accTypes_[i])); + MOZ_ALWAYS_TRUE(types_->append(mozilla::Move(ty))); + accTypes_.clear(); + } +}; +#endif // DEBUG + void CodeGeneratorShared::verifyCompactTrackedOptimizationsMap(JitCode *code, uint32_t numRegions, const UniqueTrackedOptimizations &unique, - const types::TypeSet::TypeList *allTypes) + const IonTrackedTypeVector *allTypes) { #ifdef DEBUG MOZ_ASSERT(trackedOptimizationsMap_ != nullptr); @@ -912,16 +954,18 @@ CodeGeneratorShared::verifyCompactTrackedOptimizationsMap(JitCode *code, uint32_ MOZ_ASSERT(endOffset == entry.endOffset.offset()); MOZ_ASSERT(index == unique.indexOf(entry.optimizations)); - // Assert that the type info and attempts vector are correctly - // decoded. Since this is a DEBUG-only verification, crash on OOM. + // Assert that the type info and attempts vectors are correctly + // decoded. IonTrackedOptimizationsTypeInfo typeInfo = typesTable->entry(index); - TempTrackedTypeInfoVector tvec(alloc()); - MOZ_ALWAYS_TRUE(typeInfo.readVector(&tvec, allTypes)); + TempOptimizationTypeInfoVector tvec(alloc()); + ReadTempTypeInfoVectorOp top(&tvec); + typeInfo.forEach(top, allTypes); MOZ_ASSERT(entry.optimizations->matchTypes(tvec)); IonTrackedOptimizationsAttempts attempts = attemptsTable->entry(index); - TempAttemptsVector avec(alloc()); - MOZ_ALWAYS_TRUE(attempts.readVector(&avec)); + TempOptimizationAttemptsVector avec(alloc()); + ReadTempAttemptsVectorOp aop(&avec); + attempts.forEach(aop); MOZ_ASSERT(entry.optimizations->matchAttempts(avec)); } } diff --git a/js/src/jit/shared/CodeGenerator-shared.h b/js/src/jit/shared/CodeGenerator-shared.h index 12d2354de561..604642bae38b 100644 --- a/js/src/jit/shared/CodeGenerator-shared.h +++ b/js/src/jit/shared/CodeGenerator-shared.h @@ -14,6 +14,7 @@ #include "jit/MacroAssembler.h" #include "jit/MIRGenerator.h" #include "jit/MIRGraph.h" +#include "jit/OptimizationTracking.h" #include "jit/Safepoints.h" #include "jit/Snapshots.h" #include "jit/VMFunctions.h" @@ -25,7 +26,6 @@ class OutOfLineCode; class CodeGenerator; class MacroAssembler; class IonCache; -class UniqueTrackedOptimizations; template class OutOfLineCallVM; @@ -48,6 +48,17 @@ struct ReciprocalMulConstants { int32_t shiftAmount; }; +// This should be nested in CodeGeneratorShared, but it is used in +// optimization tracking implementation and nested classes cannot be +// forward-declared. +struct NativeToTrackedOptimizations +{ + // [startOffset, endOffset] + CodeOffsetLabel startOffset; + CodeOffsetLabel endOffset; + const TrackedOptimizations *optimizations; +}; + class CodeGeneratorShared : public LElementVisitor { js::Vector outOfLineCode_; @@ -115,15 +126,6 @@ class CodeGeneratorShared : public LElementVisitor return gen->isProfilerInstrumentationEnabled(); } - public: - struct NativeToTrackedOptimizations { - // [startOffset, endOffset) - CodeOffsetLabel startOffset; - CodeOffsetLabel endOffset; - const TrackedOptimizations *optimizations; - }; - - protected: js::Vector trackedOptimizations_; uint8_t *trackedOptimizationsMap_; uint32_t trackedOptimizationsMapSize_; @@ -338,10 +340,10 @@ class CodeGeneratorShared : public LElementVisitor void verifyCompactNativeToBytecodeMap(JitCode *code); bool generateCompactTrackedOptimizationsMap(JSContext *cx, JitCode *code, - types::TypeSet::TypeList *allTypes); + IonTrackedTypeVector *allTypes); void verifyCompactTrackedOptimizationsMap(JitCode *code, uint32_t numRegions, const UniqueTrackedOptimizations &unique, - const types::TypeSet::TypeList *allTypes); + const IonTrackedTypeVector *allTypes); // Mark the safepoint on |ins| as corresponding to the current assembler location. // The location should be just after a call. diff --git a/js/src/jsapi-tests/testIntTypesABI.cpp b/js/src/jsapi-tests/testIntTypesABI.cpp index b868fb5d3551..066e7ad1b829 100644 --- a/js/src/jsapi-tests/testIntTypesABI.cpp +++ b/js/src/jsapi-tests/testIntTypesABI.cpp @@ -31,6 +31,7 @@ #include "js/SliceBudget.h" #include "js/StructuredClone.h" #include "js/TracingAPI.h" +#include "js/TrackedOptimizationInfo.h" #include "js/TypeDecls.h" #include "js/UbiNode.h" #include "js/Utility.h" diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index 6a7110915957..46b9bc70c841 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -304,6 +304,10 @@ class ExclusiveContext : public ContextFriendFields, types::ObjectGroup *getNewGroup(const Class *clasp, TaggedProto proto, JSObject *associated = nullptr); types::ObjectGroup *getLazySingletonGroup(const Class *clasp, TaggedProto proto); + + // Returns false if not found. + bool findAllocationSiteForType(types::Type ty, JSScript **script, uint32_t *offset) const; + inline js::LifoAlloc &typeLifoAlloc(); // Current global. This is only safe to use within the scope of the diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index 8c89765f0b8a..bf61065b1956 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -97,6 +97,38 @@ types::TypeIdStringImpl(jsid id) // Logging ///////////////////////////////////////////////////////////////////// +const char * +types::NonObjectTypeString(Type type) +{ + if (type.isPrimitive()) { + switch (type.primitive()) { + case JSVAL_TYPE_UNDEFINED: + return "void"; + case JSVAL_TYPE_NULL: + return "null"; + case JSVAL_TYPE_BOOLEAN: + return "bool"; + case JSVAL_TYPE_INT32: + return "int"; + case JSVAL_TYPE_DOUBLE: + return "float"; + case JSVAL_TYPE_STRING: + return "string"; + case JSVAL_TYPE_SYMBOL: + return "symbol"; + case JSVAL_TYPE_MAGIC: + return "lazyargs"; + default: + MOZ_CRASH("Bad type"); + } + } + if (type.isUnknown()) + return "unknown"; + + MOZ_ASSERT(type.isAnyObject()); + return "object"; +} + #ifdef DEBUG static bool InferSpewActive(SpewChannel channel) @@ -172,32 +204,8 @@ types::InferSpewColor(TypeSet *types) const char * types::TypeString(Type type) { - if (type.isPrimitive()) { - switch (type.primitive()) { - case JSVAL_TYPE_UNDEFINED: - return "void"; - case JSVAL_TYPE_NULL: - return "null"; - case JSVAL_TYPE_BOOLEAN: - return "bool"; - case JSVAL_TYPE_INT32: - return "int"; - case JSVAL_TYPE_DOUBLE: - return "float"; - case JSVAL_TYPE_STRING: - return "string"; - case JSVAL_TYPE_SYMBOL: - return "symbol"; - case JSVAL_TYPE_MAGIC: - return "lazyargs"; - default: - MOZ_CRASH("Bad type"); - } - } - if (type.isUnknown()) - return "unknown"; - if (type.isAnyObject()) - return " object"; + if (type.isPrimitive() || type.isUnknown() || type.isAnyObject()) + return NonObjectTypeString(type); static char bufs[4][40]; static unsigned which = 0; @@ -4710,6 +4718,30 @@ ExclusiveContext::getLazySingletonGroup(const Class *clasp, TaggedProto proto) return group; } +bool +ExclusiveContext::findAllocationSiteForType(Type type, JSScript **script, uint32_t *offset) const +{ + *script = nullptr; + *offset = 0; + + if (type.isUnknown() || type.isAnyObject() || !type.isGroup()) + return false; + ObjectGroup *obj = type.group(); + + const AllocationSiteTable *table = compartment()->types.allocationSiteTable; + if (!table) + return false; + + for (AllocationSiteTable::Range r = table->all(); !r.empty(); r.popFront()) { + if (obj == r.front().value()) { + *script = r.front().key().script; + *offset = r.front().key().offset; + return true; + } + } + return false; +} + ///////////////////////////////////////////////////////////////////// // Tracing ///////////////////////////////////////////////////////////////////// diff --git a/js/src/jsinfer.h b/js/src/jsinfer.h index efe240c1ca00..406e12a3a21c 100644 --- a/js/src/jsinfer.h +++ b/js/src/jsinfer.h @@ -1790,6 +1790,8 @@ enum SpewChannel { SPEW_COUNT }; +const char *NonObjectTypeString(Type type); + #ifdef DEBUG const char * InferSpewColorReset(); diff --git a/js/src/moz.build b/js/src/moz.build index 5a988b668a5d..239c858519b9 100644 --- a/js/src/moz.build +++ b/js/src/moz.build @@ -84,6 +84,7 @@ EXPORTS.js += [ '../public/SliceBudget.h', '../public/StructuredClone.h', '../public/TracingAPI.h', + '../public/TrackedOptimizationInfo.h', '../public/TypeDecls.h', '../public/UbiNode.h', '../public/UbiNodeTraverse.h', diff --git a/js/src/vm/Stack.cpp b/js/src/vm/Stack.cpp index 6024a5b76659..8c0dfffdd718 100644 --- a/js/src/vm/Stack.cpp +++ b/js/src/vm/Stack.cpp @@ -1866,6 +1866,8 @@ JS::ProfilingFrameIterator::extractStack(Frame *frames, uint32_t offset, uint32_ frames[offset].returnAddress = nullptr; frames[offset].activation = activation_; frames[offset].label = asmJSIter().label(); + frames[offset].hasTrackedOptimizations = false; + frames[offset].trackedOptimizationIndex = 0; return 1; } From 49af4f5b4c366fcd04cff34b5339205594de19af Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Wed, 4 Feb 2015 13:41:04 -0800 Subject: [PATCH 19/74] Bug 1127156 - Attach optimization info to frames in profiler. (r=BenWa) --- js/src/vm/Stack.cpp | 21 +++++- tools/profiler/JSStreamWriter.cpp | 14 ++++ tools/profiler/JSStreamWriter.h | 1 + tools/profiler/ProfileEntry.cpp | 103 ++++++++++++++++++++++++++++-- tools/profiler/ProfileEntry.h | 4 +- tools/profiler/TableTicker.cpp | 10 +++ 6 files changed, 144 insertions(+), 9 deletions(-) diff --git a/js/src/vm/Stack.cpp b/js/src/vm/Stack.cpp index 8c0dfffdd718..34d147c0799a 100644 --- a/js/src/vm/Stack.cpp +++ b/js/src/vm/Stack.cpp @@ -1877,8 +1877,7 @@ JS::ProfilingFrameIterator::extractStack(Frame *frames, uint32_t offset, uint32_ // Look up an entry for the return address. jit::JitcodeGlobalTable *table = rt_->jitRuntime()->getJitcodeGlobalTable(); jit::JitcodeGlobalEntry entry; - mozilla::DebugOnly result = table->lookup(returnAddr, &entry, rt_); - MOZ_ASSERT(result); + table->lookupInfallible(returnAddr, &entry, rt_); MOZ_ASSERT(entry.isIon() || entry.isIonCache() || entry.isBaseline() || entry.isDummy()); @@ -1900,7 +1899,25 @@ JS::ProfilingFrameIterator::extractStack(Frame *frames, uint32_t offset, uint32_ frames[offset + i].returnAddress = returnAddr; frames[offset + i].activation = activation_; frames[offset + i].label = labels[i]; + frames[offset + i].hasTrackedOptimizations = false; + frames[offset + i].trackedOptimizationIndex = 0; } + + // Extract the index into the side table of optimization information and + // store it on the youngest frame. All inlined frames will have the same + // optimization information by virtue of sharing the JitcodeGlobalEntry, + // but such information is only interpretable on the youngest frame. + // + // FIXMEshu: disabled until we can ensure the optimization info is live + // when we write out the JSON stream of the profile. + if (false && entry.hasTrackedOptimizations()) { + mozilla::Maybe index = entry.trackedOptimizationIndexAtAddr(returnAddr); + if (index.isSome()) { + frames[offset].hasTrackedOptimizations = true; + frames[offset].trackedOptimizationIndex = index.value(); + } + } + return depth; } diff --git a/tools/profiler/JSStreamWriter.cpp b/tools/profiler/JSStreamWriter.cpp index 5febe5b14ff4..d735cb3a7457 100644 --- a/tools/profiler/JSStreamWriter.cpp +++ b/tools/profiler/JSStreamWriter.cpp @@ -150,6 +150,20 @@ JSStreamWriter::Value(int aValue) } } +void +JSStreamWriter::Value(unsigned aValue) +{ + MOZ_ASSERT(!mNeedsName); + if (mNeedsComma && mStack.Peek() == ARRAY) { + mStream << ","; + } + mStream << aValue; + mNeedsComma = true; + if (mStack.Peek() == OBJECT) { + mNeedsName = true; + } +} + void JSStreamWriter::Value(double aValue) { diff --git a/tools/profiler/JSStreamWriter.h b/tools/profiler/JSStreamWriter.h index e55e2e15f78c..7cd1f1574c5a 100644 --- a/tools/profiler/JSStreamWriter.h +++ b/tools/profiler/JSStreamWriter.h @@ -22,6 +22,7 @@ public: void EndArray(); void Name(const char *name); void Value(int value); + void Value(unsigned value); void Value(double value); void Value(const char *value, size_t valueLength); void Value(const char *value); diff --git a/tools/profiler/ProfileEntry.cpp b/tools/profiler/ProfileEntry.cpp index 8f17736a3d99..2d4de82bf210 100644 --- a/tools/profiler/ProfileEntry.cpp +++ b/tools/profiler/ProfileEntry.cpp @@ -8,7 +8,10 @@ #include "platform.h" #include "nsThreadUtils.h" #include "nsXULAppAPI.h" + +// JS #include "jsapi.h" +#include "js/TrackedOptimizationInfo.h" // JSON #include "JSStreamWriter.h" @@ -93,8 +96,9 @@ void ProfileEntry::log() // by looking through all the use points of TableTicker.cpp. // mTagMarker (ProfilerMarker*) m // mTagData (const char*) c,s - // mTagPtr (void*) d,l,L,B (immediate backtrace), S(start-of-stack) - // mTagInt (int) n,f,y,T (thread id) + // mTagPtr (void*) d,l,L,B (immediate backtrace), S(start-of-stack), + // J (JIT code addr) + // mTagInt (int) n,f,y,o (JIT optimization info index), T (thread id) // mTagChar (char) h // mTagFloat (double) r,t,p,R (resident memory), U (unshared memory) switch (mTagName) { @@ -102,9 +106,9 @@ void ProfileEntry::log() LOGF("%c \"%s\"", mTagName, mTagMarker->GetMarkerName()); break; case 'c': case 's': LOGF("%c \"%s\"", mTagName, mTagData); break; - case 'd': case 'l': case 'L': case 'B': case 'S': + case 'd': case 'l': case 'L': case 'J': case 'B': case 'S': LOGF("%c %p", mTagName, mTagPtr); break; - case 'n': case 'f': case 'y': case 'T': + case 'n': case 'f': case 'y': case 'o': case 'T': LOGF("%c %d", mTagName, mTagInt); break; case 'h': LOGF("%c \'%c\'", mTagName, mTagChar); break; @@ -245,7 +249,72 @@ void ProfileBuffer::IterateTagsForThread(IterateTagsCallback aCallback, int aThr } } -void ProfileBuffer::StreamSamplesToJSObject(JSStreamWriter& b, int aThreadId) +class StreamOptimizationTypeInfoOp : public JS::ForEachTrackedOptimizationTypeInfoOp +{ + JSStreamWriter& mWriter; + bool mStartedTypeList; + +public: + explicit StreamOptimizationTypeInfoOp(JSStreamWriter& b) + : mWriter(b) + , mStartedTypeList(false) + { } + + void readType(const char *keyedBy, const char *name, + const char *location, unsigned lineno) MOZ_OVERRIDE { + if (!mStartedTypeList) { + mStartedTypeList = true; + mWriter.BeginObject(); + mWriter.Name("types"); + mWriter.BeginArray(); + } + + mWriter.BeginObject(); + mWriter.NameValue("keyedBy", keyedBy); + mWriter.NameValue("name", name); + if (location) { + mWriter.NameValue("location", location); + mWriter.NameValue("line", lineno); + } + mWriter.EndObject(); + } + + void operator()(JS::TrackedTypeSite site, const char *mirType) MOZ_OVERRIDE { + if (mStartedTypeList) { + mWriter.EndArray(); + mStartedTypeList = false; + } else { + mWriter.BeginObject(); + } + + mWriter.NameValue("site", JS::TrackedTypeSiteString(site)); + mWriter.NameValue("mirType", mirType); + mWriter.EndObject(); + } +}; + +class StreamOptimizationAttemptsOp : public JS::ForEachTrackedOptimizationAttemptOp +{ + JSStreamWriter& mWriter; + +public: + explicit StreamOptimizationAttemptsOp(JSStreamWriter& b) + : mWriter(b) + { } + + void operator()(JS::TrackedStrategy strategy, JS::TrackedOutcome outcome) MOZ_OVERRIDE { + mWriter.BeginObject(); + { + // Stringify the reasons for now; could stream enum values in the future + // to save space. + mWriter.NameValue("strategy", JS::TrackedStrategyString(strategy)); + mWriter.NameValue("outcome", JS::TrackedOutcomeString(outcome)); + } + mWriter.EndObject(); + } +}; + +void ProfileBuffer::StreamSamplesToJSObject(JSStreamWriter& b, int aThreadId, JSRuntime* rt) { b.BeginArray(); @@ -368,6 +437,28 @@ void ProfileBuffer::StreamSamplesToJSObject(JSStreamWriter& b, int aThreadId) b.NameValue("category", mEntries[readAheadPos].mTagInt); incBy++; } + readAheadPos = (framePos + incBy) % mEntrySize; + if (readAheadPos != mWritePos && + mEntries[readAheadPos].mTagName == 'J') { + void* pc = mEntries[readAheadPos].mTagPtr; + incBy++; + readAheadPos = (framePos + incBy) % mEntrySize; + MOZ_ASSERT(readAheadPos != mWritePos && + mEntries[readAheadPos].mTagName == 'o'); + uint32_t index = mEntries[readAheadPos].mTagInt; + + // TODOshu: cannot stream tracked optimization info if + // the JS engine has already shut down when streaming. + if (rt) { + b.Name("opts"); + b.BeginArray(); + StreamOptimizationTypeInfoOp typeInfoOp(b); + JS::ForEachTrackedOptimizationTypeInfo(rt, pc, index, typeInfoOp); + StreamOptimizationAttemptsOp attemptOp(b); + JS::ForEachTrackedOptimizationAttempt(rt, pc, index, attemptOp); + b.EndArray(); + } + } b.EndObject(); } framePos = (framePos + incBy) % mEntrySize; @@ -542,7 +633,7 @@ void ThreadProfile::StreamJSObject(JSStreamWriter& b) b.NameValue("tid", static_cast(mThreadId)); b.Name("samples"); - mBuffer->StreamSamplesToJSObject(b, mThreadId); + mBuffer->StreamSamplesToJSObject(b, mThreadId, mPseudoStack->mRuntime); b.Name("markers"); mBuffer->StreamMarkersToJSObject(b, mThreadId); diff --git a/tools/profiler/ProfileEntry.h b/tools/profiler/ProfileEntry.h index 36f93f2e1669..fff072cc5720 100644 --- a/tools/profiler/ProfileEntry.h +++ b/tools/profiler/ProfileEntry.h @@ -81,7 +81,7 @@ public: void addTag(const ProfileEntry& aTag); void IterateTagsForThread(IterateTagsCallback aCallback, int aThreadId); - void StreamSamplesToJSObject(JSStreamWriter& b, int aThreadId); + void StreamSamplesToJSObject(JSStreamWriter& b, int aThreadId, JSRuntime* rt); void StreamMarkersToJSObject(JSStreamWriter& b, int aThreadId); void DuplicateLastSample(int aThreadId); @@ -184,6 +184,8 @@ public: int64_t mRssMemory; int64_t mUssMemory; #endif + + void StreamTrackedOptimizations(JSStreamWriter& b, void* addr, uint8_t index); }; std::ostream& operator<<(std::ostream& stream, const ThreadProfile& profile); diff --git a/tools/profiler/TableTicker.cpp b/tools/profiler/TableTicker.cpp index a6ffa013ef10..8be716d9c8f8 100644 --- a/tools/profiler/TableTicker.cpp +++ b/tools/profiler/TableTicker.cpp @@ -582,6 +582,16 @@ void mergeStacksIntoProfile(ThreadProfile& aProfile, TickSample* aSample, Native if (jsStackAddr > nativeStackAddr) { MOZ_ASSERT(jsIndex >= 0); addDynamicTag(aProfile, 'c', jsFrames[jsIndex].label); + + // Stringifying optimization information is delayed until streaming + // time. To re-lookup the entry in the JitcodeGlobalTable, we need to + // store both the the JIT code address ('J') and the tracked + // optimization index ('o') in the circular buffer. + if (jsFrames[jsIndex].hasTrackedOptimizations) { + aProfile.addTag(ProfileEntry('J', jsFrames[jsIndex].returnAddress)); + aProfile.addTag(ProfileEntry('o', jsFrames[jsIndex].trackedOptimizationIndex)); + } + jsIndex--; continue; } From 324fce84c87a4cdddb60577623410823f381d689 Mon Sep 17 00:00:00 2001 From: Tom Schuster Date: Wed, 4 Feb 2015 22:50:17 +0100 Subject: [PATCH 20/74] Bug 1127494 - Remove proto parameter from JS_DefineObject. r=Waldo,bz --- dom/system/OSFileConstants.cpp | 3 +-- js/src/ctypes/CTypes.cpp | 10 +++++++--- js/src/jsapi-tests/testPropCache.cpp | 2 +- js/src/jsapi.cpp | 6 +++--- js/src/jsapi.h | 5 ++--- 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/dom/system/OSFileConstants.cpp b/dom/system/OSFileConstants.cpp index 1f5756d0232d..0d207feee9c1 100644 --- a/dom/system/OSFileConstants.cpp +++ b/dom/system/OSFileConstants.cpp @@ -804,8 +804,7 @@ JSObject *GetOrCreateObjectProperty(JSContext *cx, JS::Handle aObject JSMSG_UNEXPECTED_TYPE, aProperty, "not an object"); return nullptr; } - return JS_DefineObject(cx, aObject, aProperty, nullptr, JS::NullPtr(), - JSPROP_ENUMERATE); + return JS_DefineObject(cx, aObject, aProperty, nullptr, JSPROP_ENUMERATE); } /** diff --git a/js/src/ctypes/CTypes.cpp b/js/src/ctypes/CTypes.cpp index 97759d9c8e75..e435314ba0f8 100644 --- a/js/src/ctypes/CTypes.cpp +++ b/js/src/ctypes/CTypes.cpp @@ -996,12 +996,16 @@ DefineABIConstant(JSContext* cx, ABICode code, HandleObject prototype) { - RootedObject obj(cx, JS_DefineObject(cx, parent, name, &sCABIClass, prototype, - JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)); + RootedObject obj(cx, JS_NewObjectWithGivenProto(cx, &sCABIClass, prototype)); if (!obj) return false; JS_SetReservedSlot(obj, SLOT_ABICODE, INT_TO_JSVAL(code)); - return JS_FreezeObject(cx, obj); + + if (!JS_FreezeObject(cx, obj)) + return false; + + return JS_DefineProperty(cx, parent, name, obj, + JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); } // Set up a single type constructor for diff --git a/js/src/jsapi-tests/testPropCache.cpp b/js/src/jsapi-tests/testPropCache.cpp index dea4cf54e557..975c28fcaf75 100644 --- a/js/src/jsapi-tests/testPropCache.cpp +++ b/js/src/jsapi-tests/testPropCache.cpp @@ -26,7 +26,7 @@ BEGIN_TEST(testPropCache_bug505798) { g_counter = 0; EXEC("var x = {};"); - CHECK(JS_DefineObject(cx, global, "y", &CounterClass, JS::NullPtr(), JSPROP_ENUMERATE)); + CHECK(JS_DefineObject(cx, global, "y", &CounterClass, JSPROP_ENUMERATE)); EXEC("var arr = [x, y];\n" "for (var i = 0; i < arr.length; i++)\n" " arr[i].p = 1;\n"); diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 892022faaaa0..79947d5667e2 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -2659,17 +2659,17 @@ JS_DefineUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_ JS_PUBLIC_API(JSObject *) JS_DefineObject(JSContext *cx, HandleObject obj, const char *name, const JSClass *jsclasp, - HandleObject proto, unsigned attrs) + unsigned attrs) { AssertHeapIsIdle(cx); CHECK_REQUEST(cx); - assertSameCompartment(cx, obj, proto); + assertSameCompartment(cx, obj); const Class *clasp = Valueify(jsclasp); if (!clasp) clasp = &PlainObject::class_; /* default class is Object */ - RootedObject nobj(cx, NewObjectWithClassProto(cx, clasp, proto, obj)); + RootedObject nobj(cx, NewObjectWithClassProto(cx, clasp, nullptr, obj)); if (!nobj) return nullptr; diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 4e2ef68f5d6e..11b846908920 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -2578,7 +2578,7 @@ JS_GetObjectRuntime(JSObject *obj); */ extern JS_PUBLIC_API(JSObject *) JS_NewObjectWithGivenProto(JSContext *cx, const JSClass *clasp, JS::Handle proto, - JS::Handle parent); + JS::Handle parent = JS::NullPtr()); // Creates a new plain object, like `new Object()`, with Object.prototype as [[Prototype]]. extern JS_PUBLIC_API(JSObject *) @@ -2613,8 +2613,7 @@ JS_New(JSContext *cx, JS::HandleObject ctor, const JS::HandleValueArray& args); extern JS_PUBLIC_API(JSObject *) JS_DefineObject(JSContext *cx, JS::HandleObject obj, const char *name, - const JSClass *clasp = nullptr, JS::HandleObject proto = JS::NullPtr(), - unsigned attrs = 0); + const JSClass *clasp = nullptr, unsigned attrs = 0); extern JS_PUBLIC_API(bool) JS_DefineConstDoubles(JSContext *cx, JS::HandleObject obj, const JSConstDoubleSpec *cds); From a79546917fcbd0cbd6939e84ed13c1a70b2c1c08 Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Wed, 4 Feb 2015 13:50:56 -0800 Subject: [PATCH 21/74] Bug 1128225 (Part 1) - Return a result enumeration from imgIContainer::Draw. r=tn --- dom/canvas/CanvasRenderingContext2D.cpp | 6 ++- image/public/imgIContainer.idl | 66 ++++++++++++++++++++++--- image/src/ClippedImage.cpp | 10 ++-- image/src/ClippedImage.h | 28 +++++------ image/src/DynamicImage.cpp | 11 ++--- image/src/FrozenImage.cpp | 2 +- image/src/FrozenImage.h | 14 +++--- image/src/ImageWrapper.cpp | 2 +- image/src/OrientedImage.cpp | 2 +- image/src/OrientedImage.h | 14 +++--- image/src/RasterImage.cpp | 38 ++++++++++---- image/src/RasterImage.h | 12 ++--- image/src/VectorImage.cpp | 34 ++++++++----- 13 files changed, 159 insertions(+), 80 deletions(-) diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp index 3fd0a0935c0c..a995695e514c 100644 --- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -4452,13 +4452,15 @@ CanvasRenderingContext2D::DrawDirectlyToCanvas( SVGImageContext svgContext(scaledImageSize, Nothing(), CurrentState().globalAlpha); - nsresult rv = image.mImgContainer-> + auto result = image.mImgContainer-> Draw(context, scaledImageSize, ImageRegion::Create(gfxRect(src.x, src.y, src.width, src.height)), image.mWhichFrame, GraphicsFilter::FILTER_GOOD, Some(svgContext), modifiedFlags); - NS_ENSURE_SUCCESS_VOID(rv); + if (result != DrawResult::SUCCESS) { + NS_WARNING("imgIContainer::Draw failed"); + } } void diff --git a/image/public/imgIContainer.idl b/image/public/imgIContainer.idl index 8731e0fcd539..437d61c88ee2 100644 --- a/image/public/imgIContainer.idl +++ b/image/public/imgIContainer.idl @@ -34,13 +34,60 @@ class SVGImageContext; namespace mozilla { namespace image { + class ImageRegion; struct Orientation; + +/** + * An enumeration representing the result of a drawing operation. + * + * Most users of DrawResult will only be interested in whether the value is + * SUCCESS or not. The other values are primarily useful for debugging and error + * handling. + * + * SUCCESS: We successfully drew a completely decoded frame of the requested + * size. Drawing again with FLAG_SYNC_DECODE would not change the result. + * + * INCOMPLETE: We successfully drew a frame that was partially decoded. (Note + * that successfully drawing a partially decoded frame may not actually draw any + * pixels!) Drawing again with FLAG_SYNC_DECODE would improve the result. + * + * WRONG_SIZE: We successfully drew a wrongly-sized frame that had to be scaled. + * This is only returned if drawing again with FLAG_SYNC_DECODE would improve + * the result; if the size requested was larger than the intrinsic size of the + * image, for example, we would generally have to scale whether FLAG_SYNC_DECODE + * was specified or not, and therefore we would not return WRONG_SIZE. + * + * NOT_READY: We failed to draw because no decoded version of the image was + * available. Drawing again with FLAG_SYNC_DECODE would improve the result. + * (Though FLAG_SYNC_DECODE will not necessarily work until after the image's + * load event!) + * + * TEMPORARY_ERROR: We failed to draw due to a temporary error. Drawing may + * succeed at a later time. + * + * BAD_IMAGE: We failed to draw because the image has an error. This is a + * permanent condition. + * + * BAD_ARGS: We failed to draw because bad arguments were passed to draw(). + */ +enum class DrawResult : uint8_t +{ + SUCCESS, + INCOMPLETE, + WRONG_SIZE, + NOT_READY, + TEMPORARY_ERROR, + BAD_IMAGE, + BAD_ARGS +}; + } } %} +native DrawResult(mozilla::image::DrawResult); [ptr] native gfxContext(gfxContext); [ref] native gfxMatrix(gfxMatrix); [ref] native gfxRect(gfxRect); @@ -69,7 +116,7 @@ native nsIntSizeByVal(nsIntSize); * * Internally, imgIContainer also manages animation of images. */ -[scriptable, builtinclass, uuid(3a630c1d-3365-4873-bc01-54468decf8c6)] +[scriptable, builtinclass, uuid(4e7d0b17-cb57-4d68-860f-59b303a86dbd)] interface imgIContainer : nsISupports { /** @@ -335,14 +382,17 @@ interface imgIContainer : nsISupports * node, and the size of the viewport that the full image * would occupy. Ignored for raster images. * @param aFlags Flags of the FLAG_* variety + * @return A DrawResult value indicating whether and to what degree the + * drawing operation was successful. */ - [noscript] void draw(in gfxContext aContext, - [const] in nsIntSize aSize, - [const] in ImageRegion aRegion, - in uint32_t aWhichFrame, - in gfxGraphicsFilter aFilter, - [const] in MaybeSVGImageContext aSVGContext, - in uint32_t aFlags); + [noscript, notxpcom] DrawResult + draw(in gfxContext aContext, + [const] in nsIntSize aSize, + [const] in ImageRegion aRegion, + in uint32_t aWhichFrame, + in gfxGraphicsFilter aFilter, + [const] in MaybeSVGImageContext aSVGContext, + in uint32_t aFlags); /* * Ensures that an image is decoding. Calling this function guarantees that diff --git a/image/src/ClippedImage.cpp b/image/src/ClippedImage.cpp index 27caa70400f8..53b3e217ee74 100644 --- a/image/src/ClippedImage.cpp +++ b/image/src/ClippedImage.cpp @@ -297,7 +297,7 @@ MustCreateSurface(gfxContext* aContext, return willTile || willResample; } -NS_IMETHODIMP +NS_IMETHODIMP_(DrawResult) ClippedImage::Draw(gfxContext* aContext, const nsIntSize& aSize, const ImageRegion& aRegion, @@ -318,7 +318,9 @@ ClippedImage::Draw(gfxContext* aContext, // GetFrame will call DrawSingleTile internally. RefPtr surface = GetFrameInternal(aSize, aSVGContext, aWhichFrame, aFlags); - NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE); + if (!surface) { + return DrawResult::TEMPORARY_ERROR; + } // Create a drawable from that surface. nsRefPtr drawable = @@ -328,7 +330,7 @@ ClippedImage::Draw(gfxContext* aContext, gfxUtils::DrawPixelSnapped(aContext, drawable, aSize, aRegion, SurfaceFormat::B8G8R8A8, aFilter); - return NS_OK; + return DrawResult::SUCCESS; } return DrawSingleTile(aContext, aSize, aRegion, aWhichFrame, @@ -352,7 +354,7 @@ UnclipViewport(const SVGImageContext& aOldContext, aOldContext.GetPreserveAspectRatio()); } -nsresult +DrawResult ClippedImage::DrawSingleTile(gfxContext* aContext, const nsIntSize& aSize, const ImageRegion& aRegion, diff --git a/image/src/ClippedImage.h b/image/src/ClippedImage.h index f02211cfd3e8..c8764b714177 100644 --- a/image/src/ClippedImage.h +++ b/image/src/ClippedImage.h @@ -39,13 +39,13 @@ public: GetFrame(uint32_t aWhichFrame, uint32_t aFlags) MOZ_OVERRIDE; NS_IMETHOD GetImageContainer(layers::LayerManager* aManager, layers::ImageContainer** _retval) MOZ_OVERRIDE; - NS_IMETHOD Draw(gfxContext* aContext, - const nsIntSize& aSize, - const ImageRegion& aRegion, - uint32_t aWhichFrame, - GraphicsFilter aFilter, - const Maybe& aSVGContext, - uint32_t aFlags) MOZ_OVERRIDE; + NS_IMETHOD_(DrawResult) Draw(gfxContext* aContext, + const nsIntSize& aSize, + const ImageRegion& aRegion, + uint32_t aWhichFrame, + GraphicsFilter aFilter, + const Maybe& aSVGContext, + uint32_t aFlags) MOZ_OVERRIDE; NS_IMETHOD RequestDiscard() MOZ_OVERRIDE; NS_IMETHOD_(Orientation) GetOrientation() MOZ_OVERRIDE; NS_IMETHOD_(nsIntRect) GetImageSpaceInvalidationRect(const nsIntRect& aRect) MOZ_OVERRIDE; @@ -66,13 +66,13 @@ private: uint32_t aWhichFrame, uint32_t aFlags); bool ShouldClip(); - nsresult DrawSingleTile(gfxContext* aContext, - const nsIntSize& aSize, - const ImageRegion& aRegion, - uint32_t aWhichFrame, - GraphicsFilter aFilter, - const Maybe& aSVGContext, - uint32_t aFlags); + DrawResult DrawSingleTile(gfxContext* aContext, + const nsIntSize& aSize, + const ImageRegion& aRegion, + uint32_t aWhichFrame, + GraphicsFilter aFilter, + const Maybe& aSVGContext, + uint32_t aFlags); // If we are forced to draw a temporary surface, we cache it here. nsAutoPtr mCachedSurface; diff --git a/image/src/DynamicImage.cpp b/image/src/DynamicImage.cpp index 78b5d083cafd..cd74b546e991 100644 --- a/image/src/DynamicImage.cpp +++ b/image/src/DynamicImage.cpp @@ -186,12 +186,11 @@ DynamicImage::GetFrame(uint32_t aWhichFrame, SurfaceFormat::B8G8R8A8); nsRefPtr context = new gfxContext(dt); - nsresult rv = Draw(context, size, ImageRegion::Create(size), + auto result = Draw(context, size, ImageRegion::Create(size), aWhichFrame, GraphicsFilter::FILTER_NEAREST, Nothing(), aFlags); - NS_ENSURE_SUCCESS(rv, nullptr); - return dt->Snapshot(); + return result == DrawResult::SUCCESS ? dt->Snapshot() : nullptr; } NS_IMETHODIMP_(bool) @@ -210,7 +209,7 @@ DynamicImage::GetImageContainer(LayerManager* aManager, return NS_OK; } -NS_IMETHODIMP +NS_IMETHODIMP_(DrawResult) DynamicImage::Draw(gfxContext* aContext, const nsIntSize& aSize, const ImageRegion& aRegion, @@ -226,7 +225,7 @@ DynamicImage::Draw(gfxContext* aContext, if (aSize == drawableSize) { gfxUtils::DrawPixelSnapped(aContext, mDrawable, drawableSize, aRegion, SurfaceFormat::B8G8R8A8, aFilter); - return NS_OK; + return DrawResult::SUCCESS; } gfxSize scale(double(aSize.width) / drawableSize.width, @@ -240,7 +239,7 @@ DynamicImage::Draw(gfxContext* aContext, gfxUtils::DrawPixelSnapped(aContext, mDrawable, drawableSize, region, SurfaceFormat::B8G8R8A8, aFilter); - return NS_OK; + return DrawResult::SUCCESS; } NS_IMETHODIMP diff --git a/image/src/FrozenImage.cpp b/image/src/FrozenImage.cpp index ec3169fb97ae..5da2a109adbf 100644 --- a/image/src/FrozenImage.cpp +++ b/image/src/FrozenImage.cpp @@ -58,7 +58,7 @@ FrozenImage::GetImageContainer(layers::LayerManager* aManager, return NS_OK; } -NS_IMETHODIMP +NS_IMETHODIMP_(DrawResult) FrozenImage::Draw(gfxContext* aContext, const nsIntSize& aSize, const ImageRegion& aRegion, diff --git a/image/src/FrozenImage.h b/image/src/FrozenImage.h index c9987ddcf231..e504e523114a 100644 --- a/image/src/FrozenImage.h +++ b/image/src/FrozenImage.h @@ -39,13 +39,13 @@ public: GetFrame(uint32_t aWhichFrame, uint32_t aFlags) MOZ_OVERRIDE; NS_IMETHOD GetImageContainer(layers::LayerManager* aManager, layers::ImageContainer** _retval) MOZ_OVERRIDE; - NS_IMETHOD Draw(gfxContext* aContext, - const nsIntSize& aSize, - const ImageRegion& aRegion, - uint32_t aWhichFrame, - GraphicsFilter aFilter, - const Maybe& aSVGContext, - uint32_t aFlags) MOZ_OVERRIDE; + NS_IMETHOD_(DrawResult) Draw(gfxContext* aContext, + const nsIntSize& aSize, + const ImageRegion& aRegion, + uint32_t aWhichFrame, + GraphicsFilter aFilter, + const Maybe& aSVGContext, + uint32_t aFlags) MOZ_OVERRIDE; NS_IMETHOD_(void) RequestRefresh(const TimeStamp& aTime) MOZ_OVERRIDE; NS_IMETHOD GetAnimationMode(uint16_t* aAnimationMode) MOZ_OVERRIDE; NS_IMETHOD SetAnimationMode(uint16_t aAnimationMode) MOZ_OVERRIDE; diff --git a/image/src/ImageWrapper.cpp b/image/src/ImageWrapper.cpp index f375f25aa01d..2ddc0f68878e 100644 --- a/image/src/ImageWrapper.cpp +++ b/image/src/ImageWrapper.cpp @@ -199,7 +199,7 @@ ImageWrapper::GetImageContainer(LayerManager* aManager, return mInnerImage->GetImageContainer(aManager, _retval); } -NS_IMETHODIMP +NS_IMETHODIMP_(DrawResult) ImageWrapper::Draw(gfxContext* aContext, const nsIntSize& aSize, const ImageRegion& aRegion, diff --git a/image/src/OrientedImage.cpp b/image/src/OrientedImage.cpp index 20db2f51764a..7fea526ca677 100644 --- a/image/src/OrientedImage.cpp +++ b/image/src/OrientedImage.cpp @@ -251,7 +251,7 @@ OrientViewport(const SVGImageContext& aOldContext, aOldContext.GetPreserveAspectRatio()); } -NS_IMETHODIMP +NS_IMETHODIMP_(DrawResult) OrientedImage::Draw(gfxContext* aContext, const nsIntSize& aSize, const ImageRegion& aRegion, diff --git a/image/src/OrientedImage.h b/image/src/OrientedImage.h index 244c3c7ad74e..62f53d2c8ed0 100644 --- a/image/src/OrientedImage.h +++ b/image/src/OrientedImage.h @@ -36,13 +36,13 @@ public: GetFrame(uint32_t aWhichFrame, uint32_t aFlags) MOZ_OVERRIDE; NS_IMETHOD GetImageContainer(layers::LayerManager* aManager, layers::ImageContainer** _retval) MOZ_OVERRIDE; - NS_IMETHOD Draw(gfxContext* aContext, - const nsIntSize& aSize, - const ImageRegion& aRegion, - uint32_t aWhichFrame, - GraphicsFilter aFilter, - const Maybe& aSVGContext, - uint32_t aFlags) MOZ_OVERRIDE; + NS_IMETHOD_(DrawResult) Draw(gfxContext* aContext, + const nsIntSize& aSize, + const ImageRegion& aRegion, + uint32_t aWhichFrame, + GraphicsFilter aFilter, + const Maybe& aSVGContext, + uint32_t aFlags) MOZ_OVERRIDE; NS_IMETHOD_(nsIntRect) GetImageSpaceInvalidationRect( const nsIntRect& aRect) MOZ_OVERRIDE; nsIntSize OptimalImageSizeForDest(const gfxSize& aDest, diff --git a/image/src/RasterImage.cpp b/image/src/RasterImage.cpp index 3f96f6687ced..9a9c8a7281ba 100644 --- a/image/src/RasterImage.cpp +++ b/image/src/RasterImage.cpp @@ -1699,7 +1699,7 @@ RasterImage::RequestScale(imgFrame* aFrame, } } -void +DrawResult RasterImage::DrawWithPreDownscaleIfNeeded(DrawableFrameRef&& aFrameRef, gfxContext* aContext, const nsIntSize& aSize, @@ -1728,23 +1728,39 @@ RasterImage::DrawWithPreDownscaleIfNeeded(DrawableFrameRef&& aFrameRef, gfxContextMatrixAutoSaveRestore saveMatrix(aContext); ImageRegion region(aRegion); + bool frameIsComplete = true; // We already checked HQ scaled frames. if (!frameRef) { + // There's no HQ scaled frame available, so we'll have to use the frame + // provided by the caller. frameRef = Move(aFrameRef); + frameIsComplete = frameRef->IsImageComplete(); } // By now we may have a frame with the requested size. If not, we need to // adjust the drawing parameters accordingly. IntSize finalSize = frameRef->GetImageSize(); + bool couldRedecodeForBetterFrame = false; if (ThebesIntSize(finalSize) != aSize) { gfx::Size scale(double(aSize.width) / finalSize.width, double(aSize.height) / finalSize.height); aContext->Multiply(gfxMatrix::Scaling(scale.width, scale.height)); region.Scale(1.0 / scale.width, 1.0 / scale.height); + + couldRedecodeForBetterFrame = mDownscaleDuringDecode && + CanDownscaleDuringDecode(aSize, aFlags); } if (!frameRef->Draw(aContext, region, aFilter, aFlags)) { RecoverFromLossOfFrames(aSize, aFlags); + return DrawResult::TEMPORARY_ERROR; } + if (!frameIsComplete) { + return DrawResult::INCOMPLETE; + } + if (couldRedecodeForBetterFrame) { + return DrawResult::WRONG_SIZE; + } + return DrawResult::SUCCESS; } //****************************************************************************** @@ -1757,7 +1773,7 @@ RasterImage::DrawWithPreDownscaleIfNeeded(DrawableFrameRef&& aFrameRef, * [const] in SVGImageContext aSVGContext, * in uint32_t aWhichFrame, * in uint32_t aFlags); */ -NS_IMETHODIMP +NS_IMETHODIMP_(DrawResult) RasterImage::Draw(gfxContext* aContext, const nsIntSize& aSize, const ImageRegion& aRegion, @@ -1767,18 +1783,20 @@ RasterImage::Draw(gfxContext* aContext, uint32_t aFlags) { if (aWhichFrame > FRAME_MAX_VALUE) - return NS_ERROR_INVALID_ARG; + return DrawResult::BAD_ARGS; if (mError) - return NS_ERROR_FAILURE; + return DrawResult::BAD_IMAGE; // Illegal -- you can't draw with non-default decode flags. // (Disabling colorspace conversion might make sense to allow, but // we don't currently.) if (DecodeFlags(aFlags) != DECODE_FLAGS_DEFAULT) - return NS_ERROR_FAILURE; + return DrawResult::BAD_ARGS; - NS_ENSURE_ARG_POINTER(aContext); + if (!aContext) { + return DrawResult::BAD_ARGS; + } if (IsUnlocked() && mProgressTracker) { mProgressTracker->OnUnlockedDraw(); @@ -1797,14 +1815,14 @@ RasterImage::Draw(gfxContext* aContext, if (mDrawStartTime.IsNull()) { mDrawStartTime = TimeStamp::Now(); } - return NS_OK; + return DrawResult::NOT_READY; } bool shouldRecordTelemetry = !mDrawStartTime.IsNull() && ref->IsImageComplete(); - DrawWithPreDownscaleIfNeeded(Move(ref), aContext, aSize, - aRegion, aFilter, flags); + auto result = DrawWithPreDownscaleIfNeeded(Move(ref), aContext, aSize, + aRegion, aFilter, flags); if (shouldRecordTelemetry) { TimeDuration drawLatency = TimeStamp::Now() - mDrawStartTime; @@ -1813,7 +1831,7 @@ RasterImage::Draw(gfxContext* aContext, mDrawStartTime = TimeStamp(); } - return NS_OK; + return result; } //****************************************************************************** diff --git a/image/src/RasterImage.h b/image/src/RasterImage.h index d152ccface95..6c0072f8cbb2 100644 --- a/image/src/RasterImage.h +++ b/image/src/RasterImage.h @@ -288,12 +288,12 @@ public: } private: - void DrawWithPreDownscaleIfNeeded(DrawableFrameRef&& aFrameRef, - gfxContext* aContext, - const nsIntSize& aSize, - const ImageRegion& aRegion, - GraphicsFilter aFilter, - uint32_t aFlags); + DrawResult DrawWithPreDownscaleIfNeeded(DrawableFrameRef&& aFrameRef, + gfxContext* aContext, + const nsIntSize& aSize, + const ImageRegion& aRegion, + GraphicsFilter aFilter, + uint32_t aFlags); TemporaryRef CopyFrame(uint32_t aWhichFrame, uint32_t aFlags); diff --git a/image/src/VectorImage.cpp b/image/src/VectorImage.cpp index 86179f73d045..5841734a45cc 100644 --- a/image/src/VectorImage.cpp +++ b/image/src/VectorImage.cpp @@ -687,13 +687,12 @@ VectorImage::GetFrame(uint32_t aWhichFrame, nsRefPtr context = new gfxContext(dt); - nsresult rv = Draw(context, imageIntSize, + auto result = Draw(context, imageIntSize, ImageRegion::Create(imageIntSize), aWhichFrame, GraphicsFilter::FILTER_NEAREST, Nothing(), aFlags); - NS_ENSURE_SUCCESS(rv, nullptr); - return dt->Snapshot(); + return result == DrawResult::SUCCESS ? dt->Snapshot() : nullptr; } //****************************************************************************** @@ -747,7 +746,7 @@ struct SVGDrawingParameters * in gfxGraphicsFilter aFilter, * [const] in MaybeSVGImageContext aSVGContext, * in uint32_t aFlags); */ -NS_IMETHODIMP +NS_IMETHODIMP_(DrawResult) VectorImage::Draw(gfxContext* aContext, const nsIntSize& aSize, const ImageRegion& aRegion, @@ -756,16 +755,25 @@ VectorImage::Draw(gfxContext* aContext, const Maybe& aSVGContext, uint32_t aFlags) { - if (aWhichFrame > FRAME_MAX_VALUE) - return NS_ERROR_INVALID_ARG; + if (aWhichFrame > FRAME_MAX_VALUE) { + return DrawResult::BAD_ARGS; + } - NS_ENSURE_ARG_POINTER(aContext); - if (mError || !mIsFullyLoaded) - return NS_ERROR_FAILURE; + if (!aContext) { + return DrawResult::BAD_ARGS; + } + + if (mError) { + return DrawResult::BAD_IMAGE; + } + + if (!mIsFullyLoaded) { + return DrawResult::NOT_READY; + } if (mIsDrawing) { NS_WARNING("Refusing to make re-entrant call to VectorImage::Draw"); - return NS_ERROR_FAILURE; + return DrawResult::TEMPORARY_ERROR; } if (mAnimationConsumers == 0 && mProgressTracker) { @@ -786,7 +794,7 @@ VectorImage::Draw(gfxContext* aContext, if (aFlags & FLAG_BYPASS_SURFACE_CACHE) { CreateSurfaceAndShow(params); - return NS_OK; + return DrawResult::SUCCESS; } DrawableFrameRef frameRef = @@ -802,7 +810,7 @@ VectorImage::Draw(gfxContext* aContext, nsRefPtr svgDrawable = new gfxSurfaceDrawable(surface, ThebesIntSize(frameRef->GetSize())); Show(svgDrawable, params); - return NS_OK; + return DrawResult::SUCCESS; } // We lost our surface due to some catastrophic event. @@ -811,7 +819,7 @@ VectorImage::Draw(gfxContext* aContext, CreateSurfaceAndShow(params); - return NS_OK; + return DrawResult::SUCCESS; } void From 16240133276513c7e1f484ce8f2757ee24cc290b Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Wed, 4 Feb 2015 13:50:56 -0800 Subject: [PATCH 22/74] Bug 1128225 (Part 2) - Propagate the imgIContainer::Draw result through the nsLayoutUtils::Draw*Image functions. r=tn --- layout/base/nsLayoutUtils.cpp | 33 +++++++++------ layout/base/nsLayoutUtils.h | 75 ++++++++++++++++++----------------- 2 files changed, 58 insertions(+), 50 deletions(-) diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 6da06c3d4a0c..45ccae6b15e5 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -5872,7 +5872,7 @@ ComputeSnappedImageDrawingParameters(gfxContext* aCtx, } -static nsresult +static DrawResult DrawImageInternal(gfxContext& aContext, nsPresContext* aPresContext, imgIContainer* aImage, @@ -5900,8 +5900,9 @@ DrawImageInternal(gfxContext& aContext, aFill, aAnchor, aDirty, aImage, aGraphicsFilter, aImageFlags); - if (!params.shouldDraw) - return NS_OK; + if (!params.shouldDraw) { + return DrawResult::SUCCESS; + } gfxContextMatrixAutoSaveRestore contextMatrixRestorer(&aContext); aContext.SetMatrix(params.imageSpaceToDeviceSpace); @@ -5912,13 +5913,12 @@ DrawImageInternal(gfxContext& aContext, svgContext = Some(SVGImageContext(params.svgViewportSize, Nothing())); } - aImage->Draw(&aContext, params.size, params.region, imgIContainer::FRAME_CURRENT, - aGraphicsFilter, svgContext, aImageFlags); - - return NS_OK; + return aImage->Draw(&aContext, params.size, params.region, + imgIContainer::FRAME_CURRENT, aGraphicsFilter, + svgContext, aImageFlags); } -/* static */ nsresult +/* static */ DrawResult nsLayoutUtils::DrawSingleUnscaledImage(gfxContext& aContext, nsPresContext* aPresContext, imgIContainer* aImage, @@ -5931,7 +5931,10 @@ nsLayoutUtils::DrawSingleUnscaledImage(gfxContext& aContext, nsIntSize imageSize; aImage->GetWidth(&imageSize.width); aImage->GetHeight(&imageSize.height); - NS_ENSURE_TRUE(imageSize.width > 0 && imageSize.height > 0, NS_ERROR_FAILURE); + if (imageSize.width < 1 || imageSize.height < 1) { + NS_WARNING("Image width or height is non-positive"); + return DrawResult::TEMPORARY_ERROR; + } nscoord appUnitsPerCSSPixel = nsDeviceContext::AppUnitsPerCSSPixel(); nsSize size(imageSize.width*appUnitsPerCSSPixel, @@ -5956,7 +5959,7 @@ nsLayoutUtils::DrawSingleUnscaledImage(gfxContext& aContext, nullptr, aImageFlags); } -/* static */ nsresult +/* static */ DrawResult nsLayoutUtils::DrawSingleImage(gfxContext& aContext, nsPresContext* aPresContext, imgIContainer* aImage, @@ -5970,7 +5973,11 @@ nsLayoutUtils::DrawSingleImage(gfxContext& aContext, { nscoord appUnitsPerCSSPixel = nsDeviceContext::AppUnitsPerCSSPixel(); nsIntSize pixelImageSize(ComputeSizeForDrawingWithFallback(aImage, aDest.Size())); - NS_ENSURE_TRUE(pixelImageSize.width > 0 && pixelImageSize.height > 0, NS_ERROR_FAILURE); + if (pixelImageSize.width < 1 || pixelImageSize.height < 1) { + NS_WARNING("Image width or height is non-positive"); + return DrawResult::TEMPORARY_ERROR; + } + nsSize imageSize(pixelImageSize.width * appUnitsPerCSSPixel, pixelImageSize.height * appUnitsPerCSSPixel); @@ -6069,7 +6076,7 @@ nsLayoutUtils::ComputeSizeForDrawingWithFallback(imgIContainer* aImage, return imageSize; } -/* static */ nsresult +/* static */ DrawResult nsLayoutUtils::DrawBackgroundImage(gfxContext& aContext, nsPresContext* aPresContext, imgIContainer* aImage, @@ -6095,7 +6102,7 @@ nsLayoutUtils::DrawBackgroundImage(gfxContext& aContext, aDirty, &svgContext, aImageFlags); } -/* static */ nsresult +/* static */ DrawResult nsLayoutUtils::DrawImage(gfxContext& aContext, nsPresContext* aPresContext, imgIContainer* aImage, diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index 5a8b0540e1b3..4b52970eadcd 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -127,6 +127,7 @@ class nsLayoutUtils typedef mozilla::gfx::Matrix4x4 Matrix4x4; typedef mozilla::gfx::RectCornerRadii RectCornerRadii; typedef mozilla::gfx::StrokeOptions StrokeOptions; + typedef mozilla::image::DrawResult DrawResult; public: typedef mozilla::layers::FrameMetrics FrameMetrics; @@ -1657,16 +1658,16 @@ public: * @param aDirty Pixels outside this area may be skipped. * @param aImageFlags Image flags of the imgIContainer::FLAG_* variety */ - static nsresult DrawBackgroundImage(gfxContext& aContext, - nsPresContext* aPresContext, - imgIContainer* aImage, - const nsIntSize& aImageSize, - GraphicsFilter aGraphicsFilter, - const nsRect& aDest, - const nsRect& aFill, - const nsPoint& aAnchor, - const nsRect& aDirty, - uint32_t aImageFlags); + static DrawResult DrawBackgroundImage(gfxContext& aContext, + nsPresContext* aPresContext, + imgIContainer* aImage, + const nsIntSize& aImageSize, + GraphicsFilter aGraphicsFilter, + const nsRect& aDest, + const nsRect& aFill, + const nsPoint& aAnchor, + const nsRect& aDirty, + uint32_t aImageFlags); /** * Draw an image. @@ -1683,15 +1684,15 @@ public: * @param aDirty Pixels outside this area may be skipped. * @param aImageFlags Image flags of the imgIContainer::FLAG_* variety */ - static nsresult DrawImage(gfxContext& aContext, - nsPresContext* aPresContext, - imgIContainer* aImage, - GraphicsFilter aGraphicsFilter, - const nsRect& aDest, - const nsRect& aFill, - const nsPoint& aAnchor, - const nsRect& aDirty, - uint32_t aImageFlags); + static DrawResult DrawImage(gfxContext& aContext, + nsPresContext* aPresContext, + imgIContainer* aImage, + GraphicsFilter aGraphicsFilter, + const nsRect& aDest, + const nsRect& aFill, + const nsPoint& aAnchor, + const nsRect& aDirty, + uint32_t aImageFlags); static inline void InitDashPattern(StrokeOptions& aStrokeOptions, uint8_t aBorderStyle) { @@ -1737,14 +1738,14 @@ public: * in appunits. For best results it should * be aligned with image pixels. */ - static nsresult DrawSingleUnscaledImage(gfxContext& aContext, - nsPresContext* aPresContext, - imgIContainer* aImage, - GraphicsFilter aGraphicsFilter, - const nsPoint& aDest, - const nsRect* aDirty, - uint32_t aImageFlags, - const nsRect* aSourceArea = nullptr); + static DrawResult DrawSingleUnscaledImage(gfxContext& aContext, + nsPresContext* aPresContext, + imgIContainer* aImage, + GraphicsFilter aGraphicsFilter, + const nsPoint& aDest, + const nsRect* aDirty, + uint32_t aImageFlags, + const nsRect* aSourceArea = nullptr); /** * Draw a whole image without tiling. @@ -1768,16 +1769,16 @@ public: * in appunits. For best results it should * be aligned with image pixels. */ - static nsresult DrawSingleImage(gfxContext& aContext, - nsPresContext* aPresContext, - imgIContainer* aImage, - GraphicsFilter aGraphicsFilter, - const nsRect& aDest, - const nsRect& aDirty, - const mozilla::SVGImageContext* aSVGContext, - uint32_t aImageFlags, - const nsPoint* aAnchorPoint = nullptr, - const nsRect* aSourceArea = nullptr); + static DrawResult DrawSingleImage(gfxContext& aContext, + nsPresContext* aPresContext, + imgIContainer* aImage, + GraphicsFilter aGraphicsFilter, + const nsRect& aDest, + const nsRect& aDirty, + const mozilla::SVGImageContext* aSVGContext, + uint32_t aImageFlags, + const nsPoint* aAnchorPoint = nullptr, + const nsRect* aSourceArea = nullptr); /** * Given an imgIContainer, this method attempts to obtain an intrinsic From 347d961b260c7564fdfc6fde3b5f14614114a8d3 Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Wed, 4 Feb 2015 13:50:56 -0800 Subject: [PATCH 23/74] Bug 1128225 (Part 3) - Add infrastructure for tracking draw results in geometry items. r=tn --- layout/base/FrameLayerBuilder.cpp | 25 +++++++++++ layout/base/FrameLayerBuilder.h | 12 +++++ layout/base/nsDisplayListInvalidation.h | 59 +++++++++++++++++++++++++ 3 files changed, 96 insertions(+) diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp index 323b934b4f2b..a2d22740874f 100644 --- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -4732,6 +4732,31 @@ FrameLayerBuilder::DumpRetainedLayerTree(LayerManager* aManager, std::stringstre aManager->Dump(aStream, "", aDumpHtml); } +nsDisplayItemGeometry* +FrameLayerBuilder::GetMostRecentGeometry(nsDisplayItem* aItem) +{ + typedef nsTArray DataArray; + + // Retrieve the array of DisplayItemData associated with our frame. + FrameProperties properties = aItem->Frame()->Properties(); + auto dataArray = + static_cast(properties.Get(LayerManagerDataProperty())); + if (!dataArray) { + return nullptr; + } + + // Find our display item data, if it exists, and return its geometry. + uint32_t itemPerFrameKey = aItem->GetPerFrameKey(); + for (uint32_t i = 0; i < dataArray->Length(); i++) { + DisplayItemData* data = dataArray->ElementAt(i); + if (data->GetDisplayItemKey() == itemPerFrameKey) { + return data->GetGeometry(); + } + } + + return nullptr; +} + gfx::Rect CalculateBounds(const nsTArray& aRects, int32_t A2D) { diff --git a/layout/base/FrameLayerBuilder.h b/layout/base/FrameLayerBuilder.h index 86c51f97ee0b..4a5a2186098f 100644 --- a/layout/base/FrameLayerBuilder.h +++ b/layout/base/FrameLayerBuilder.h @@ -275,6 +275,17 @@ public: */ static void DumpRetainedLayerTree(LayerManager* aManager, std::stringstream& aStream, bool aDumpHtml = false); + /** + * Returns the most recently allocated geometry item for the given display + * item. + * + * XXX(seth): The current implementation must iterate through all display + * items allocated for this display item's frame. This may lead to O(n^2) + * behavior in some situations. + */ + static nsDisplayItemGeometry* GetMostRecentGeometry(nsDisplayItem* aItem); + + /******* PRIVATE METHODS to FrameLayerBuilder.cpp ********/ /* These are only in the public section because they need * to be called by file-scope helper functions in FrameLayerBuilder.cpp. @@ -398,6 +409,7 @@ public: uint32_t GetDisplayItemKey() { return mDisplayItemKey; } Layer* GetLayer() { return mLayer; } + nsDisplayItemGeometry* GetGeometry() const { return mGeometry.get(); } void Invalidate() { mIsInvalid = true; } private: diff --git a/layout/base/nsDisplayListInvalidation.h b/layout/base/nsDisplayListInvalidation.h index 5e2b12546328..1dd0219ffc9f 100644 --- a/layout/base/nsDisplayListInvalidation.h +++ b/layout/base/nsDisplayListInvalidation.h @@ -7,6 +7,8 @@ #define NSDISPLAYLISTINVALIDATION_H_ #include "mozilla/Attributes.h" +#include "FrameLayerBuilder.h" +#include "imgIContainer.h" #include "nsRect.h" #include "nsColor.h" #include "gfxRect.h" @@ -71,6 +73,63 @@ public: nsRect mBorderRect; }; +/** + * nsImageGeometryMixin is a mixin for geometry items that draw images. Geometry + * items that include this mixin can track drawing results and use that + * information to inform invalidation decisions. + * + * This mixin uses CRTP; its template parameter should be the type of the class + * that is inheriting from it. See nsDisplayItemGenericImageGeometry for an + * example. + */ +template +class nsImageGeometryMixin +{ +public: + explicit nsImageGeometryMixin(nsDisplayItem* aItem) + : mLastDrawResult(mozilla::image::DrawResult::NOT_READY) + { + auto lastGeometry = + static_cast(mozilla::FrameLayerBuilder::GetMostRecentGeometry(aItem)); + if (lastGeometry) { + mLastDrawResult = lastGeometry->LastDrawResult(); + } + } + + static void UpdateDrawResult(nsDisplayItem* aItem, + mozilla::image::DrawResult aResult) + { + auto lastGeometry = + static_cast(mozilla::FrameLayerBuilder::GetMostRecentGeometry(aItem)); + if (lastGeometry) { + lastGeometry->mLastDrawResult = aResult; + } + } + + mozilla::image::DrawResult LastDrawResult() const { return mLastDrawResult; } + +private: + mozilla::image::DrawResult mLastDrawResult; +}; + +/** + * nsDisplayItemGenericImageGeometry is a generic geometry item class that + * includes nsImageGeometryMixin. + * + * This should be sufficient for most display items that draw images. + */ +class nsDisplayItemGenericImageGeometry + : public nsDisplayItemGenericGeometry + , public nsImageGeometryMixin +{ +public: + nsDisplayItemGenericImageGeometry(nsDisplayItem* aItem, + nsDisplayListBuilder* aBuilder) + : nsDisplayItemGenericGeometry(aItem, aBuilder) + , nsImageGeometryMixin(aItem) + { } +}; + class nsDisplayItemBoundsGeometry : public nsDisplayItemGeometry { public: From 8c44fcc6686575d0f8017e408e3e29b1eb361e4c Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Wed, 4 Feb 2015 13:50:56 -0800 Subject: [PATCH 24/74] Bug 1128225 (Part 4) - Record the last draw result in nsDisplayImage and use it to decide whether to sync decode. r=tn --- layout/generic/nsImageFrame.cpp | 37 ++++++++++++++++++++++++++------- layout/generic/nsImageFrame.h | 9 +++++--- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index 8a8d224e1e3c..cd01682b0c9b 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -79,6 +79,7 @@ using namespace mozilla; using namespace mozilla::dom; using namespace mozilla::gfx; +using namespace mozilla::image; using namespace mozilla::layers; // sizes (pixels) for image icon, padding and border frame @@ -1403,8 +1404,17 @@ nsDisplayImage::Paint(nsDisplayListBuilder* aBuilder, if (aBuilder->IsPaintingToWindow()) { flags |= imgIContainer::FLAG_HIGH_QUALITY_SCALING; } - static_cast(mFrame)-> + + DrawResult result = static_cast(mFrame)-> PaintImage(*aCtx, ToReferenceFrame(), mVisibleRect, mImage, flags); + + nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result); +} + +nsDisplayItemGeometry* +nsDisplayImage::AllocateGeometry(nsDisplayListBuilder* aBuilder) +{ + return new nsDisplayItemGenericImageGeometry(this, aBuilder); } void @@ -1412,7 +1422,11 @@ nsDisplayImage::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, const nsDisplayItemGeometry* aGeometry, nsRegion* aInvalidRegion) { - if (aBuilder->ShouldSyncDecodeImages() && mImage && !mImage->IsDecoded()) { + auto geometry = + static_cast(aGeometry); + + if (aBuilder->ShouldSyncDecodeImages() && + geometry->LastDrawResult() != DrawResult::SUCCESS) { bool snap; aInvalidRegion->Or(*aInvalidRegion, GetBounds(aBuilder, &snap)); } @@ -1558,6 +1572,12 @@ nsDisplayImage::ConfigureLayer(ImageLayer *aLayer, const nsIntPoint& aOffset) mImage->GetHeight(&imageHeight); NS_ASSERTION(imageWidth != 0 && imageHeight != 0, "Invalid image size!"); + if (imageWidth > 0 && imageHeight > 0) { + // We're actually using the ImageContainer. Let our frame know that it + // should consider itself to have painted successfully. + nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, + DrawResult::SUCCESS); + } const gfxRect destRect = GetDestRect(); @@ -1568,7 +1588,7 @@ nsDisplayImage::ConfigureLayer(ImageLayer *aLayer, const nsIntPoint& aOffset) aLayer->SetBaseTransform(gfx::Matrix4x4::From2D(transform)); } -void +DrawResult nsImageFrame::PaintImage(nsRenderingContext& aRenderingContext, nsPoint aPt, const nsRect& aDirtyRect, imgIContainer* aImage, uint32_t aFlags) @@ -1593,10 +1613,11 @@ nsImageFrame::PaintImage(nsRenderingContext& aRenderingContext, nsPoint aPt, StylePosition(), &anchorPoint); - nsLayoutUtils::DrawSingleImage(*aRenderingContext.ThebesContext(), - PresContext(), aImage, - nsLayoutUtils::GetGraphicsFilterForFrame(this), dest, aDirtyRect, - nullptr, aFlags, &anchorPoint); + DrawResult result = + nsLayoutUtils::DrawSingleImage(*aRenderingContext.ThebesContext(), + PresContext(), aImage, + nsLayoutUtils::GetGraphicsFilterForFrame(this), dest, aDirtyRect, + nullptr, aFlags, &anchorPoint); nsImageMap* map = GetImageMap(); if (map) { @@ -1617,6 +1638,8 @@ nsImageFrame::PaintImage(nsRenderingContext& aRenderingContext, nsPoint aPt, nsLayoutUtils::InitDashPattern(strokeOptions, NS_STYLE_BORDER_STYLE_DOTTED); map->Draw(this, *drawTarget, black, strokeOptions); } + + return result; } void diff --git a/layout/generic/nsImageFrame.h b/layout/generic/nsImageFrame.h index 1a695e8eec79..f6f6f62a4cf1 100644 --- a/layout/generic/nsImageFrame.h +++ b/layout/generic/nsImageFrame.h @@ -63,6 +63,7 @@ typedef nsSplittableFrame ImageFrameSuper; class nsImageFrame : public ImageFrameSuper, public nsIReflowCallback { public: + typedef mozilla::image::DrawResult DrawResult; typedef mozilla::layers::ImageContainer ImageContainer; typedef mozilla::layers::ImageLayer ImageLayer; typedef mozilla::layers::LayerManager LayerManager; @@ -214,9 +215,9 @@ protected: const nsString& aAltText, const nsRect& aRect); - void PaintImage(nsRenderingContext& aRenderingContext, nsPoint aPt, - const nsRect& aDirtyRect, imgIContainer* aImage, - uint32_t aFlags); + DrawResult PaintImage(nsRenderingContext& aRenderingContext, nsPoint aPt, + const nsRect& aDirtyRect, imgIContainer* aImage, + uint32_t aFlags); protected: friend class nsImageListener; @@ -373,6 +374,8 @@ public: virtual ~nsDisplayImage() { MOZ_COUNT_DTOR(nsDisplayImage); } + + virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE; virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, const nsDisplayItemGeometry* aGeometry, nsRegion* aInvalidRegion) MOZ_OVERRIDE; From 48c5abfdb03adbfac8a6e83125df5308c3e86bb2 Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Wed, 4 Feb 2015 13:50:56 -0800 Subject: [PATCH 25/74] Bug 1128225 (Part 5) - Record the last draw result in nsDisplayBullet and use it to decide whether to sync decode. r=tn --- layout/generic/nsBulletFrame.cpp | 25 ++++++++++++++++--------- layout/generic/nsBulletFrame.h | 7 +++++-- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/layout/generic/nsBulletFrame.cpp b/layout/generic/nsBulletFrame.cpp index c8251f19c503..3e4cfc399a34 100644 --- a/layout/generic/nsBulletFrame.cpp +++ b/layout/generic/nsBulletFrame.cpp @@ -39,6 +39,7 @@ using namespace mozilla; using namespace mozilla::gfx; +using namespace mozilla::image; NS_DECLARE_FRAME_PROPERTY(FontSizeInflationProperty, nullptr) @@ -169,11 +170,14 @@ nsBulletFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext) #endif } -class nsDisplayBulletGeometry : public nsDisplayItemGenericGeometry +class nsDisplayBulletGeometry + : public nsDisplayItemGenericGeometry + , public nsImageGeometryMixin { public: nsDisplayBulletGeometry(nsDisplayItem* aItem, nsDisplayListBuilder* aBuilder) : nsDisplayItemGenericGeometry(aItem, aBuilder) + , nsImageGeometryMixin(aItem) { nsBulletFrame* f = static_cast(aItem->Frame()); mOrdinal = f->GetOrdinal(); @@ -234,10 +238,8 @@ public: } nsCOMPtr image = f->GetImage(); - if (aBuilder->ShouldSyncDecodeImages() && image && !image->IsDecoded()) { - // If we are going to do a sync decode and we are not decoded then we are - // going to be drawing something different from what is currently there, - // so we add our bounds to the invalid region. + if (aBuilder->ShouldSyncDecodeImages() && image && + geometry->LastDrawResult() != DrawResult::SUCCESS) { bool snap; aInvalidRegion->Or(*aInvalidRegion, GetBounds(aBuilder, &snap)); } @@ -253,8 +255,11 @@ void nsDisplayBullet::Paint(nsDisplayListBuilder* aBuilder, if (aBuilder->ShouldSyncDecodeImages()) { flags |= imgIContainer::FLAG_SYNC_DECODE; } - static_cast(mFrame)-> + + DrawResult result = static_cast(mFrame)-> PaintBullet(*aCtx, ToReferenceFrame(), mVisibleRect, flags); + + nsDisplayBulletGeometry::UpdateDrawResult(this, result); } void @@ -271,7 +276,7 @@ nsBulletFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, new (aBuilder) nsDisplayBullet(aBuilder, this)); } -void +DrawResult nsBulletFrame::PaintBullet(nsRenderingContext& aRenderingContext, nsPoint aPt, const nsRect& aDirtyRect, uint32_t aFlags) { @@ -290,11 +295,11 @@ nsBulletFrame::PaintBullet(nsRenderingContext& aRenderingContext, nsPoint aPt, nsRect dest(padding.left, padding.top, mRect.width - (padding.left + padding.right), mRect.height - (padding.top + padding.bottom)); - nsLayoutUtils::DrawSingleImage(*aRenderingContext.ThebesContext(), + return + nsLayoutUtils::DrawSingleImage(*aRenderingContext.ThebesContext(), PresContext(), imageCon, nsLayoutUtils::GetGraphicsFilterForFrame(this), dest + aPt, aDirtyRect, nullptr, aFlags); - return; } } } @@ -432,6 +437,8 @@ nsBulletFrame::PaintBullet(nsRenderingContext& aRenderingContext, nsPoint aPt, } break; } + + return DrawResult::SUCCESS; } int32_t diff --git a/layout/generic/nsBulletFrame.h b/layout/generic/nsBulletFrame.h index 598ab0db4f32..bb4a5320fa08 100644 --- a/layout/generic/nsBulletFrame.h +++ b/layout/generic/nsBulletFrame.h @@ -11,6 +11,7 @@ #include "mozilla/Attributes.h" #include "nsFrame.h" +#include "imgIContainer.h" #include "imgINotificationObserver.h" #include "imgIOnloadBlocker.h" @@ -42,6 +43,8 @@ private: * This class also supports the CSS list-style properties. */ class nsBulletFrame MOZ_FINAL : public nsFrame { + typedef mozilla::image::DrawResult DrawResult; + public: NS_DECL_FRAMEARENA_HELPERS #ifdef DEBUG @@ -90,8 +93,8 @@ public: void GetSpokenText(nsAString& aText); - void PaintBullet(nsRenderingContext& aRenderingContext, nsPoint aPt, - const nsRect& aDirtyRect, uint32_t aFlags); + DrawResult PaintBullet(nsRenderingContext& aRenderingContext, nsPoint aPt, + const nsRect& aDirtyRect, uint32_t aFlags); virtual bool IsEmpty() MOZ_OVERRIDE; virtual bool IsSelfEmpty() MOZ_OVERRIDE; From e9b08641d5ed1bc4ab92e770b91b96ccde4044f3 Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Wed, 4 Feb 2015 13:50:56 -0800 Subject: [PATCH 26/74] Bug 1128225 (Part 6) - Record the last draw result in nsDisplayXULImage and use it to decide whether to sync decode. r=tn --- layout/xul/nsImageBoxFrame.cpp | 51 +++++++++++++++++++++++----------- layout/xul/nsImageBoxFrame.h | 8 ++++-- 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/layout/xul/nsImageBoxFrame.cpp b/layout/xul/nsImageBoxFrame.cpp index b8185a2a4353..e4b5566ef9e4 100644 --- a/layout/xul/nsImageBoxFrame.cpp +++ b/layout/xul/nsImageBoxFrame.cpp @@ -56,6 +56,7 @@ using namespace mozilla; using namespace mozilla::gfx; +using namespace mozilla::image; using namespace mozilla::layers; class nsImageBoxFrameEvent : public nsRunnable @@ -317,7 +318,7 @@ nsImageBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, aLists.Content()->AppendToTop(&list); } -void +DrawResult nsImageBoxFrame::PaintImage(nsRenderingContext& aRenderingContext, const nsRect& aDirtyRect, nsPoint aPt, uint32_t aFlags) @@ -327,25 +328,32 @@ nsImageBoxFrame::PaintImage(nsRenderingContext& aRenderingContext, rect += aPt; - if (!mImageRequest) - return; + if (!mImageRequest) { + // This probably means we're drawn by a native theme. + return DrawResult::SUCCESS; + } // don't draw if the image is not dirty + // XXX(seth): Can this actually happen anymore? nsRect dirty; - if (!dirty.IntersectRect(aDirtyRect, rect)) - return; + if (!dirty.IntersectRect(aDirtyRect, rect)) { + return DrawResult::TEMPORARY_ERROR; + } nsCOMPtr imgCon; mImageRequest->GetImage(getter_AddRefs(imgCon)); if (imgCon) { bool hasSubRect = !mUseSrcAttr && (mSubRect.width > 0 || mSubRect.height > 0); - nsLayoutUtils::DrawSingleImage(*aRenderingContext.ThebesContext(), + return + nsLayoutUtils::DrawSingleImage(*aRenderingContext.ThebesContext(), PresContext(), imgCon, nsLayoutUtils::GetGraphicsFilterForFrame(this), rect, dirty, nullptr, aFlags, nullptr, hasSubRect ? &mSubRect : nullptr); } + + return DrawResult::NOT_READY; } void nsDisplayXULImage::Paint(nsDisplayListBuilder* aBuilder, @@ -357,8 +365,16 @@ void nsDisplayXULImage::Paint(nsDisplayListBuilder* aBuilder, if (aBuilder->IsPaintingToWindow()) flags |= imgIContainer::FLAG_HIGH_QUALITY_SCALING; - static_cast(mFrame)-> + DrawResult result = static_cast(mFrame)-> PaintImage(*aCtx, mVisibleRect, ToReferenceFrame(), flags); + + nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result); +} + +nsDisplayItemGeometry* +nsDisplayXULImage::AllocateGeometry(nsDisplayListBuilder* aBuilder) +{ + return new nsDisplayItemGenericImageGeometry(this, aBuilder); } void @@ -366,18 +382,15 @@ nsDisplayXULImage::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, const nsDisplayItemGeometry* aGeometry, nsRegion* aInvalidRegion) { + auto boxFrame = static_cast(mFrame); + auto geometry = + static_cast(aGeometry); - if (aBuilder->ShouldSyncDecodeImages()) { - nsImageBoxFrame* boxFrame = static_cast(mFrame); - nsCOMPtr image; - if (boxFrame->mImageRequest) { - boxFrame->mImageRequest->GetImage(getter_AddRefs(image)); - } - - if (image && !image->IsDecoded()) { + if (aBuilder->ShouldSyncDecodeImages() && + boxFrame->mImageRequest && + geometry->LastDrawResult() != DrawResult::SUCCESS) { bool snap; aInvalidRegion->Or(*aInvalidRegion, GetBounds(aBuilder, &snap)); - } } nsDisplayImageContainer::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion); @@ -405,6 +418,12 @@ nsDisplayXULImage::ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset) imgCon->GetHeight(&imageHeight); NS_ASSERTION(imageWidth != 0 && imageHeight != 0, "Invalid image size!"); + if (imageWidth > 0 && imageHeight > 0) { + // We're actually using the ImageContainer. Let our frame know that it + // should consider itself to have painted successfully. + nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, + DrawResult::SUCCESS); + } gfxPoint p = destRect.TopLeft() + aOffset; Matrix transform = Matrix::Translation(p.x, p.y); diff --git a/layout/xul/nsImageBoxFrame.h b/layout/xul/nsImageBoxFrame.h index 05c6615b5c5e..4580fe0141ed 100644 --- a/layout/xul/nsImageBoxFrame.h +++ b/layout/xul/nsImageBoxFrame.h @@ -40,6 +40,7 @@ private: class nsImageBoxFrame MOZ_FINAL : public nsLeafBoxFrame { public: + typedef mozilla::image::DrawResult DrawResult; typedef mozilla::layers::LayerManager LayerManager; friend class nsDisplayXULImage; @@ -90,9 +91,9 @@ public: virtual ~nsImageBoxFrame(); - void PaintImage(nsRenderingContext& aRenderingContext, - const nsRect& aDirtyRect, - nsPoint aPt, uint32_t aFlags); + DrawResult PaintImage(nsRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsPoint aPt, uint32_t aFlags); already_AddRefed GetContainer(LayerManager* aManager); protected: @@ -146,6 +147,7 @@ public: *aSnap = true; return nsRect(ToReferenceFrame(), Frame()->GetSize()); } + virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE; virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, const nsDisplayItemGeometry* aGeometry, nsRegion* aInvalidRegion) MOZ_OVERRIDE; From a3e940d7ae1d973409df334668df21c09d07deb2 Mon Sep 17 00:00:00 2001 From: Blake Kaplan Date: Wed, 4 Feb 2015 14:17:13 -0800 Subject: [PATCH 27/74] Bug 1120395 - Deal with shutdown without crashing. r=mmc/gcp --- .../url-classifier/nsUrlClassifierStreamUpdater.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp b/toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp index 0a903360f544..7556d672fd90 100644 --- a/toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp +++ b/toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp @@ -493,10 +493,16 @@ nsUrlClassifierStreamUpdater::OnStartRequest(nsIRequest *request, if (downloadError) { LOG(("nsUrlClassifierStreamUpdater::Download error [this=%p]", this)); - mDownloadErrorCallback->HandleEvent(strStatus); + + // It's possible for mDownloadErrorCallback to be null on shutdown. + if (mDownloadErrorCallback) { + mDownloadErrorCallback->HandleEvent(strStatus); + } + mDownloadError = true; status = NS_ERROR_ABORT; } else if (NS_SUCCEEDED(status)) { + MOZ_ASSERT(mDownloadErrorCallback); mBeganStream = true; LOG(("nsUrlClassifierStreamUpdater::Beginning stream [this=%p]", this)); rv = mDBService->BeginStream(mStreamTable); From a45c78dc89c49971f44ae8fff947f1466def5c21 Mon Sep 17 00:00:00 2001 From: Markus Stange Date: Wed, 4 Feb 2015 17:25:18 -0500 Subject: [PATCH 28/74] Bug 1045213 - Make ns(Int)Region methods chainable. r=jrmuizel --- gfx/src/nsRegion.h | 48 +++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/gfx/src/nsRegion.h b/gfx/src/nsRegion.h index 32a207ddf1d8..0ed92aa4f4ae 100644 --- a/gfx/src/nsRegion.h +++ b/gfx/src/nsRegion.h @@ -128,13 +128,13 @@ public: return Copy(TmpRect); } - void OrWith(const nsRegion& aOther) + nsRegion& OrWith(const nsRegion& aOther) { - Or(*this, aOther); + return Or(*this, aOther); } - void OrWith(const nsRect& aOther) + nsRegion& OrWith(const nsRect& aOther) { - Or(*this, aOther); + return Or(*this, aOther); } nsRegion& Or(const nsRegion& aRgn1, const nsRegion& aRgn2) { @@ -156,13 +156,13 @@ public: return Or (*this, aRect2); } - void XorWith(const nsRegion& aOther) + nsRegion& XorWith(const nsRegion& aOther) { - Xor(*this, aOther); + return Xor(*this, aOther); } - void XorWith(const nsRect& aOther) + nsRegion& XorWith(const nsRect& aOther) { - Xor(*this, aOther); + return Xor(*this, aOther); } nsRegion& Xor(const nsRegion& aRgn1, const nsRegion& aRgn2) { @@ -189,13 +189,13 @@ public: nsRegion ToAppUnits (nscoord aAppUnitsPerPixel) const; - void SubOut(const nsRegion& aOther) + nsRegion& SubOut(const nsRegion& aOther) { - Sub(*this, aOther); + return Sub(*this, aOther); } - void SubOut(const nsRect& aOther) + nsRegion& SubOut(const nsRect& aOther) { - Sub(*this, aOther); + return Sub(*this, aOther); } nsRegion& Sub(const nsRegion& aRgn1, const nsRegion& aRgn2) { @@ -522,13 +522,13 @@ public: return *this; } - void OrWith(const nsIntRegion& aOther) + nsIntRegion& OrWith(const nsIntRegion& aOther) { - Or(*this, aOther); + return Or(*this, aOther); } - void OrWith(const nsIntRect& aOther) + nsIntRegion& OrWith(const nsIntRect& aOther) { - Or(*this, aOther); + return Or(*this, aOther); } nsIntRegion& Or (const nsIntRegion& aRgn1, const nsIntRegion& aRgn2) { @@ -550,13 +550,13 @@ public: return Or (*this, aRect2); } - void XorWith(const nsIntRegion& aOther) + nsIntRegion& XorWith(const nsIntRegion& aOther) { - Xor(*this, aOther); + return Xor(*this, aOther); } - void XorWith(const nsIntRect& aOther) + nsIntRegion& XorWith(const nsIntRect& aOther) { - Xor(*this, aOther); + return Xor(*this, aOther); } nsIntRegion& Xor (const nsIntRegion& aRgn1, const nsIntRegion& aRgn2) { @@ -578,13 +578,13 @@ public: return Xor (*this, aRect2); } - void SubOut(const nsIntRegion& aOther) + nsIntRegion& SubOut(const nsIntRegion& aOther) { - Sub(*this, aOther); + return Sub(*this, aOther); } - void SubOut(const nsIntRect& aOther) + nsIntRegion& SubOut(const nsIntRect& aOther) { - Sub(*this, aOther); + return Sub(*this, aOther); } nsIntRegion& Sub (const nsIntRegion& aRgn1, const nsIntRegion& aRgn2) { From fd3d5eb0f0c070b89baeb1d7c17d9ad770b33558 Mon Sep 17 00:00:00 2001 From: Markus Stange Date: Wed, 4 Feb 2015 17:25:18 -0500 Subject: [PATCH 29/74] Bug 1045213 - Use vibrancy effect for context menus. r=smichaud --- layout/base/nsDisplayList.cpp | 3 + widget/cocoa/VibrancyManager.h | 3 +- widget/cocoa/VibrancyManager.mm | 7 ++- widget/cocoa/nsChildView.mm | 12 ++++ widget/cocoa/nsNativeThemeCocoa.mm | 93 +++++++++++++++++------------- 5 files changed, 75 insertions(+), 43 deletions(-) diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 63f88809429d..ad00feac1c17 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -2796,6 +2796,9 @@ nsDisplayThemedBackground::nsDisplayThemedBackground(nsDisplayListBuilder* aBuil case NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR: case NS_THEME_TOOLBAR: case NS_THEME_TOOLTIP: + case NS_THEME_MENUPOPUP: + case NS_THEME_MENUITEM: + case NS_THEME_CHECKMENUITEM: case NS_THEME_WINDOW_TITLEBAR: case NS_THEME_WINDOW_BUTTON_BOX: case NS_THEME_MOZ_MAC_FULLSCREEN_BUTTON: diff --git a/widget/cocoa/VibrancyManager.h b/widget/cocoa/VibrancyManager.h index d37df8932f62..e8a8b6aba91a 100644 --- a/widget/cocoa/VibrancyManager.h +++ b/widget/cocoa/VibrancyManager.h @@ -24,7 +24,8 @@ namespace mozilla { enum class VibrancyType { LIGHT, DARK, - TOOLTIP + TOOLTIP, + MENU }; /** diff --git a/widget/cocoa/VibrancyManager.mm b/widget/cocoa/VibrancyManager.mm index e24efa03ed4d..25c35e60cf1b 100644 --- a/widget/cocoa/VibrancyManager.mm +++ b/widget/cocoa/VibrancyManager.mm @@ -162,6 +162,7 @@ AppearanceForVibrancyType(VibrancyType aType) switch (aType) { case VibrancyType::LIGHT: case VibrancyType::TOOLTIP: + case VibrancyType::MENU: return [NSAppearanceClass performSelector:@selector(appearanceNamed:) withObject:@"NSAppearanceNameVibrantLight"]; case VibrancyType::DARK: @@ -189,9 +190,9 @@ VibrancyManager::CreateEffectView(VibrancyType aType, NSRect aRect) NSView* effectView = [[EffectViewClass alloc] initWithFrame:aRect]; [effectView performSelector:@selector(setAppearance:) withObject:AppearanceForVibrancyType(aType)]; - if (aType == VibrancyType::TOOLTIP) { - // Tooltip windows never become active, so we need to tell the vibrancy - // effect to look active regardless of window state. + if (aType == VibrancyType::TOOLTIP || aType == VibrancyType::MENU) { + // Tooltip and menu windows never become active, so we need to tell the + // vibrancy effect to look active regardless of window state. [effectView setState:NSVisualEffectStateActive]; } return effectView; diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm index 369eadd17ed3..5b46f7a1c8da 100644 --- a/widget/cocoa/nsChildView.mm +++ b/widget/cocoa/nsChildView.mm @@ -2373,16 +2373,24 @@ nsChildView::UpdateVibrancy(const nsTArray& aThemeGeometries) GatherThemeGeometryRegion(aThemeGeometries, NS_THEME_MAC_VIBRANCY_LIGHT); nsIntRegion vibrantDarkRegion = GatherThemeGeometryRegion(aThemeGeometries, NS_THEME_MAC_VIBRANCY_DARK); + nsIntRegion menuRegion = + GatherThemeGeometryRegion(aThemeGeometries, NS_THEME_MENUPOPUP).OrWith( + GatherThemeGeometryRegion(aThemeGeometries, NS_THEME_MENUITEM).OrWith( + GatherThemeGeometryRegion(aThemeGeometries, NS_THEME_CHECKMENUITEM))); nsIntRegion tooltipRegion = GatherThemeGeometryRegion(aThemeGeometries, NS_THEME_TOOLTIP); vibrantDarkRegion.SubOut(vibrantLightRegion); + vibrantDarkRegion.SubOut(menuRegion); vibrantDarkRegion.SubOut(tooltipRegion); + vibrantLightRegion.SubOut(menuRegion); vibrantLightRegion.SubOut(tooltipRegion); + menuRegion.SubOut(tooltipRegion); auto& vm = EnsureVibrancyManager(); vm.UpdateVibrantRegion(VibrancyType::LIGHT, vibrantLightRegion); vm.UpdateVibrantRegion(VibrancyType::TOOLTIP, tooltipRegion); + vm.UpdateVibrantRegion(VibrancyType::MENU, menuRegion); vm.UpdateVibrantRegion(VibrancyType::DARK, vibrantDarkRegion); } @@ -2404,6 +2412,10 @@ WidgetTypeToVibrancyType(uint8_t aWidgetType) return VibrancyType::DARK; case NS_THEME_TOOLTIP: return VibrancyType::TOOLTIP; + case NS_THEME_MENUPOPUP: + case NS_THEME_MENUITEM: + case NS_THEME_CHECKMENUITEM: + return VibrancyType::MENU; default: MOZ_CRASH(); } diff --git a/widget/cocoa/nsNativeThemeCocoa.mm b/widget/cocoa/nsNativeThemeCocoa.mm index fe325ea686d4..59e8614de95f 100644 --- a/widget/cocoa/nsNativeThemeCocoa.mm +++ b/widget/cocoa/nsNativeThemeCocoa.mm @@ -2256,16 +2256,24 @@ nsNativeThemeCocoa::DrawResizer(CGContextRef cgContext, const HIRect& aRect, static void DrawVibrancyBackground(CGContextRef cgContext, CGRect inBoxRect, - nsIFrame* aFrame, uint8_t aWidgetType) + nsIFrame* aFrame, uint8_t aWidgetType, + int aCornerRadius = 0) { ChildView* childView = ChildViewForFrame(aFrame); if (childView) { + NSRect rect = NSRectFromCGRect(inBoxRect); NSGraphicsContext* savedContext = [NSGraphicsContext currentContext]; [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:cgContext flipped:YES]]; + [NSGraphicsContext saveGraphicsState]; + + if (aCornerRadius > 0) { + [[NSBezierPath bezierPathWithRoundedRect:rect xRadius:aCornerRadius yRadius:aCornerRadius] addClip]; + } [[childView vibrancyFillColorForWidgetType:aWidgetType] set]; - NSRectFill(NSRectFromCGRect(inBoxRect)); + NSRectFill(rect); + [NSGraphicsContext restoreGraphicsState]; [NSGraphicsContext setCurrentContext:savedContext]; } } @@ -2381,24 +2389,27 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext, } break; - case NS_THEME_MENUPOPUP: { - HIThemeMenuDrawInfo mdi; - memset(&mdi, 0, sizeof(mdi)); - mdi.version = 0; - mdi.menuType = IsDisabled(aFrame, eventState) ? - static_cast(kThemeMenuTypeInactive) : - static_cast(kThemeMenuTypePopUp); + case NS_THEME_MENUPOPUP: + if (VibrancyManager::SystemSupportsVibrancy()) { + DrawVibrancyBackground(cgContext, macRect, aFrame, aWidgetType, 4); + } else { + HIThemeMenuDrawInfo mdi; + memset(&mdi, 0, sizeof(mdi)); + mdi.version = 0; + mdi.menuType = IsDisabled(aFrame, eventState) ? + static_cast(kThemeMenuTypeInactive) : + static_cast(kThemeMenuTypePopUp); - bool isLeftOfParent = false; - if (IsSubmenu(aFrame, &isLeftOfParent) && !isLeftOfParent) { - mdi.menuType = kThemeMenuTypeHierarchical; + bool isLeftOfParent = false; + if (IsSubmenu(aFrame, &isLeftOfParent) && !isLeftOfParent) { + mdi.menuType = kThemeMenuTypeHierarchical; + } + + // The rounded corners draw outside the frame. + CGRect deflatedRect = CGRectMake(macRect.origin.x, macRect.origin.y + 4, + macRect.size.width, macRect.size.height - 8); + HIThemeDrawMenuBackground(&deflatedRect, &mdi, cgContext, HITHEME_ORIENTATION); } - - // The rounded corners draw outside the frame. - CGRect deflatedRect = CGRectMake(macRect.origin.x, macRect.origin.y + 4, - macRect.size.width, macRect.size.height - 8); - HIThemeDrawMenuBackground(&deflatedRect, &mdi, cgContext, HITHEME_ORIENTATION); - } break; case NS_THEME_MENUARROW: { @@ -2410,29 +2421,27 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext, case NS_THEME_MENUITEM: case NS_THEME_CHECKMENUITEM: { - SurfaceFormat format = thebesCtx->GetDrawTarget()->GetFormat(); - bool isTransparent = (format == SurfaceFormat::R8G8B8A8) || - (format == SurfaceFormat::B8G8R8A8); - if (isTransparent) { - // Clear the background to get correct transparency. - CGContextClearRect(cgContext, macRect); + bool isDisabled = IsDisabled(aFrame, eventState); + bool isSelected = !isDisabled && CheckBooleanAttr(aFrame, nsGkAtoms::menuactive); + if (!isSelected && VibrancyManager::SystemSupportsVibrancy()) { + DrawVibrancyBackground(cgContext, macRect, aFrame, aWidgetType); + } else { + // maybe use kThemeMenuItemHierBackground or PopUpBackground instead of just Plain? + HIThemeMenuItemDrawInfo drawInfo; + memset(&drawInfo, 0, sizeof(drawInfo)); + drawInfo.version = 0; + drawInfo.itemType = kThemeMenuItemPlain; + drawInfo.state = (isDisabled ? + static_cast(kThemeMenuDisabled) : + isSelected ? + static_cast(kThemeMenuSelected) : + static_cast(kThemeMenuActive)); + + // XXX pass in the menu rect instead of always using the item rect + HIRect ignored; + HIThemeDrawMenuItem(&macRect, &macRect, &drawInfo, cgContext, HITHEME_ORIENTATION, &ignored); } - // maybe use kThemeMenuItemHierBackground or PopUpBackground instead of just Plain? - HIThemeMenuItemDrawInfo drawInfo; - memset(&drawInfo, 0, sizeof(drawInfo)); - drawInfo.version = 0; - drawInfo.itemType = kThemeMenuItemPlain; - drawInfo.state = (IsDisabled(aFrame, eventState) ? - static_cast(kThemeMenuDisabled) : - CheckBooleanAttr(aFrame, nsGkAtoms::menuactive) ? - static_cast(kThemeMenuSelected) : - static_cast(kThemeMenuActive)); - - // XXX pass in the menu rect instead of always using the item rect - HIRect ignored; - HIThemeDrawMenuItem(&macRect, &macRect, &drawInfo, cgContext, HITHEME_ORIENTATION, &ignored); - if (aWidgetType == NS_THEME_CHECKMENUITEM) { DrawMenuIcon(cgContext, macRect, eventState, aFrame, kCheckmarkSize, kCheckmarkImage, false); } @@ -3751,6 +3760,9 @@ nsNativeThemeCocoa::NeedToClearBackgroundBehindWidget(uint8_t aWidgetType) case NS_THEME_MAC_VIBRANCY_LIGHT: case NS_THEME_MAC_VIBRANCY_DARK: case NS_THEME_TOOLTIP: + case NS_THEME_MENUPOPUP: + case NS_THEME_MENUITEM: + case NS_THEME_CHECKMENUITEM: return true; default: return false; @@ -3775,6 +3787,9 @@ nsNativeThemeCocoa::WidgetProvidesFontSmoothingBackgroundColor(nsIFrame* aFrame, case NS_THEME_MAC_VIBRANCY_LIGHT: case NS_THEME_MAC_VIBRANCY_DARK: case NS_THEME_TOOLTIP: + case NS_THEME_MENUPOPUP: + case NS_THEME_MENUITEM: + case NS_THEME_CHECKMENUITEM: { ChildView* childView = ChildViewForFrame(aFrame); if (childView) { From 2f12e52126155531d2766fccd1dfdc4f74ba5d6d Mon Sep 17 00:00:00 2001 From: Markus Stange Date: Wed, 4 Feb 2015 17:25:18 -0500 Subject: [PATCH 30/74] Bug 1045213 - Add nsITheme::ThemeGeometryTypeForWidget. r=roc --- gfx/src/nsITheme.h | 33 ++++++++++++++-- layout/base/nsDisplayList.cpp | 34 +++++++---------- widget/cocoa/nsChildView.h | 8 ++-- widget/cocoa/nsChildView.mm | 58 ++++++++++++++--------------- widget/cocoa/nsNativeThemeCocoa.h | 14 +++++++ widget/cocoa/nsNativeThemeCocoa.mm | 47 +++++++++++++++++++---- widget/nsIWidget.h | 12 +++--- widget/windows/nsNativeThemeWin.cpp | 13 +++++++ widget/windows/nsNativeThemeWin.h | 6 +++ widget/windows/nsWindow.cpp | 3 +- 10 files changed, 154 insertions(+), 74 deletions(-) diff --git a/gfx/src/nsITheme.h b/gfx/src/nsITheme.h index 063eb68a2c83..9263251a2b95 100644 --- a/gfx/src/nsITheme.h +++ b/gfx/src/nsITheme.h @@ -28,10 +28,10 @@ class nsIAtom; class nsIWidget; // IID for the nsITheme interface -// {cc3a6c72-50c2-414d-b9f2-b778a5e0f136} +// {a21dd936-5960-46da-a724-7c114e421b41} #define NS_ITHEME_IID \ -{ 0xcc3a6c72, 0x50c2, 0x414d, \ - { 0xb9, 0xf2, 0xb7, 0x78, 0xa5, 0xe0, 0xf1, 0x36 } } +{ 0xa21dd936, 0x5960, 0x46da, \ + { 0xa7, 0x24, 0x7c, 0x11, 0x4e, 0x42, 0x1b, 0x41 } } // {0ae05515-cf7a-45a8-9e02-6556de7685b1} #define NS_THEMERENDERER_CID \ { 0x0ae05515, 0xcf7a, 0x45a8, \ @@ -147,6 +147,33 @@ public: uint8_t aWidgetType, nscolor* aColor) { return false; } + /** + * ThemeGeometryType values are used for describing themed nsIFrames in + * calls to nsIWidget::UpdateThemeGeometries. We don't simply pass the + * -moz-appearance value ("widget type") of the frame because the widget may + * want to treat different frames with the same -moz-appearance differently + * based on other properties of the frame. So we give the theme a first look + * at the frame in nsITheme::ThemeGeometryTypeForWidget and pass the + * returned ThemeGeometryType along to the widget. + * Each theme backend defines the ThemeGeometryType values it needs in its + * own nsITheme subclass. eThemeGeometryTypeUnknown is the only value that's + * shared between backends. + */ + typedef uint8_t ThemeGeometryType; + enum { + eThemeGeometryTypeUnknown = 0 + }; + + /** + * Returns the theme geometry type that should be used in the ThemeGeometry + * array that's passed to the widget using nsIWidget::UpdateThemeGeometries. + * A return value of eThemeGeometryTypeUnknown means that this frame will + * not be included in the ThemeGeometry array. + */ + virtual ThemeGeometryType ThemeGeometryTypeForWidget(nsIFrame* aFrame, + uint8_t aWidgetType) + { return eThemeGeometryTypeUnknown; } + /** * Can the nsITheme implementation handle this widget? */ diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index ad00feac1c17..d3cdbbcabe31 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -2114,12 +2114,13 @@ nsDisplaySolidColor::WriteDebugInfo(std::stringstream& aStream) } static void -RegisterThemeGeometry(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) +RegisterThemeGeometry(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, + nsITheme::ThemeGeometryType aType) { if (aBuilder->IsInRootChromeDocument() && !aBuilder->IsInTransform()) { nsIFrame* displayRoot = nsLayoutUtils::GetDisplayRootFrame(aFrame); nsRect borderBox(aFrame->GetOffsetTo(displayRoot), aFrame->GetSize()); - aBuilder->RegisterThemeGeometry(aFrame->StyleDisplay()->mAppearance, + aBuilder->RegisterThemeGeometry(aType, borderBox.ToNearestPixels(aFrame->PresContext()->AppUnitsPerDevPixel())); } } @@ -2792,25 +2793,16 @@ nsDisplayThemedBackground::nsDisplayThemedBackground(nsDisplayListBuilder* aBuil mFrame->IsThemed(disp, &mThemeTransparency); // Perform necessary RegisterThemeGeometry - switch (disp->mAppearance) { - case NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR: - case NS_THEME_TOOLBAR: - case NS_THEME_TOOLTIP: - case NS_THEME_MENUPOPUP: - case NS_THEME_MENUITEM: - case NS_THEME_CHECKMENUITEM: - case NS_THEME_WINDOW_TITLEBAR: - case NS_THEME_WINDOW_BUTTON_BOX: - case NS_THEME_MOZ_MAC_FULLSCREEN_BUTTON: - case NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED: - case NS_THEME_MAC_VIBRANCY_LIGHT: - case NS_THEME_MAC_VIBRANCY_DARK: - RegisterThemeGeometry(aBuilder, aFrame); - break; - case NS_THEME_WIN_BORDERLESS_GLASS: - case NS_THEME_WIN_GLASS: - aBuilder->SetGlassDisplayItem(this); - break; + nsITheme* theme = mFrame->PresContext()->GetTheme(); + nsITheme::ThemeGeometryType type = + theme->ThemeGeometryTypeForWidget(mFrame, disp->mAppearance); + if (type != nsITheme::eThemeGeometryTypeUnknown) { + RegisterThemeGeometry(aBuilder, aFrame, type); + } + + if (disp->mAppearance == NS_THEME_WIN_BORDERLESS_GLASS || + disp->mAppearance == NS_THEME_WIN_GLASS) { + aBuilder->SetGlassDisplayItem(this); } mBounds = GetBoundsInternal(); diff --git a/widget/cocoa/nsChildView.h b/widget/cocoa/nsChildView.h index a1be2604df40..3a979b43d172 100644 --- a/widget/cocoa/nsChildView.h +++ b/widget/cocoa/nsChildView.h @@ -277,8 +277,8 @@ typedef NSInteger NSEventGestureAxis; - (BOOL)isCoveringTitlebar; -- (NSColor*)vibrancyFillColorForWidgetType:(uint8_t)aWidgetType; -- (NSColor*)vibrancyFontSmoothingBackgroundColorForWidgetType:(uint8_t)aWidgetType; +- (NSColor*)vibrancyFillColorForThemeGeometryType:(nsITheme::ThemeGeometryType)aThemeGeometryType; +- (NSColor*)vibrancyFontSmoothingBackgroundColorForThemeGeometryType:(nsITheme::ThemeGeometryType)aThemeGeometryType; // Simple gestures support // @@ -502,8 +502,8 @@ public: } void ClearVibrantAreas(); - NSColor* VibrancyFillColorForWidgetType(uint8_t aWidgetType); - NSColor* VibrancyFontSmoothingBackgroundColorForWidgetType(uint8_t aWidgetType); + NSColor* VibrancyFillColorForThemeGeometryType(nsITheme::ThemeGeometryType aThemeGeometryType); + NSColor* VibrancyFontSmoothingBackgroundColorForThemeGeometryType(nsITheme::ThemeGeometryType aThemeGeometryType); // unit conversion convenience functions int32_t CocoaPointsToDevPixels(CGFloat aPts) const { diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm index 5b46f7a1c8da..9a9cf93678ae 100644 --- a/widget/cocoa/nsChildView.mm +++ b/widget/cocoa/nsChildView.mm @@ -88,6 +88,7 @@ #include "nsLayoutUtils.h" #include "InputData.h" #include "VibrancyManager.h" +#include "nsNativeThemeCocoa.h" using namespace mozilla; using namespace mozilla::layers; @@ -2276,7 +2277,7 @@ FindTitlebarBottom(const nsTArray& aThemeGeometries, int32_t titlebarBottom = 0; for (uint32_t i = 0; i < aThemeGeometries.Length(); ++i) { const nsIWidget::ThemeGeometry& g = aThemeGeometries[i]; - if ((g.mWidgetType == NS_THEME_WINDOW_TITLEBAR) && + if ((g.mType == nsNativeThemeCocoa::eThemeGeometryTypeTitlebar) && g.mRect.X() <= 0 && g.mRect.XMost() >= aWindowWidth && g.mRect.Y() <= 0) { @@ -2293,8 +2294,7 @@ FindUnifiedToolbarBottom(const nsTArray& aThemeGeometr int32_t unifiedToolbarBottom = aTitlebarBottom; for (uint32_t i = 0; i < aThemeGeometries.Length(); ++i) { const nsIWidget::ThemeGeometry& g = aThemeGeometries[i]; - if ((g.mWidgetType == NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR || - g.mWidgetType == NS_THEME_TOOLBAR) && + if ((g.mType == nsNativeThemeCocoa::eThemeGeometryTypeToolbar) && g.mRect.X() <= 0 && g.mRect.XMost() >= aWindowWidth && g.mRect.Y() <= aTitlebarBottom) { @@ -2306,11 +2306,11 @@ FindUnifiedToolbarBottom(const nsTArray& aThemeGeometr static nsIntRect FindFirstRectOfType(const nsTArray& aThemeGeometries, - uint8_t aWidgetType) + nsITheme::ThemeGeometryType aThemeGeometryType) { for (uint32_t i = 0; i < aThemeGeometries.Length(); ++i) { const nsIWidget::ThemeGeometry& g = aThemeGeometries[i]; - if (g.mWidgetType == aWidgetType) { + if (g.mType == aThemeGeometryType) { return g.mRect; } } @@ -2342,20 +2342,20 @@ nsChildView::UpdateThemeGeometries(const nsTArray& aThemeGeometri [win setUnifiedToolbarHeight:DevPixelsToCocoaPoints(devUnifiedHeight)]; // Update titlebar control offsets. - nsIntRect windowButtonRect = FindFirstRectOfType(aThemeGeometries, NS_THEME_WINDOW_BUTTON_BOX); + nsIntRect windowButtonRect = FindFirstRectOfType(aThemeGeometries, nsNativeThemeCocoa::eThemeGeometryTypeWindowButtons); [win placeWindowButtons:[mView convertRect:DevPixelsToCocoaPoints(windowButtonRect) toView:nil]]; - nsIntRect fullScreenButtonRect = FindFirstRectOfType(aThemeGeometries, NS_THEME_MOZ_MAC_FULLSCREEN_BUTTON); + nsIntRect fullScreenButtonRect = FindFirstRectOfType(aThemeGeometries, nsNativeThemeCocoa::eThemeGeometryTypeFullscreenButton); [win placeFullScreenButton:[mView convertRect:DevPixelsToCocoaPoints(fullScreenButtonRect) toView:nil]]; } static nsIntRegion GatherThemeGeometryRegion(const nsTArray& aThemeGeometries, - uint8_t aWidgetType) + nsITheme::ThemeGeometryType aThemeGeometryType) { nsIntRegion region; for (size_t i = 0; i < aThemeGeometries.Length(); ++i) { const nsIWidget::ThemeGeometry& g = aThemeGeometries[i]; - if (g.mWidgetType == aWidgetType) { + if (g.mType == aThemeGeometryType) { region.OrWith(g.mRect); } } @@ -2370,15 +2370,13 @@ nsChildView::UpdateVibrancy(const nsTArray& aThemeGeometries) } nsIntRegion vibrantLightRegion = - GatherThemeGeometryRegion(aThemeGeometries, NS_THEME_MAC_VIBRANCY_LIGHT); + GatherThemeGeometryRegion(aThemeGeometries, nsNativeThemeCocoa::eThemeGeometryTypeVibrancyLight); nsIntRegion vibrantDarkRegion = - GatherThemeGeometryRegion(aThemeGeometries, NS_THEME_MAC_VIBRANCY_DARK); + GatherThemeGeometryRegion(aThemeGeometries, nsNativeThemeCocoa::eThemeGeometryTypeVibrancyDark); nsIntRegion menuRegion = - GatherThemeGeometryRegion(aThemeGeometries, NS_THEME_MENUPOPUP).OrWith( - GatherThemeGeometryRegion(aThemeGeometries, NS_THEME_MENUITEM).OrWith( - GatherThemeGeometryRegion(aThemeGeometries, NS_THEME_CHECKMENUITEM))); + GatherThemeGeometryRegion(aThemeGeometries, nsNativeThemeCocoa::eThemeGeometryTypeMenu); nsIntRegion tooltipRegion = - GatherThemeGeometryRegion(aThemeGeometries, NS_THEME_TOOLTIP); + GatherThemeGeometryRegion(aThemeGeometries, nsNativeThemeCocoa::eThemeGeometryTypeTooltip); vibrantDarkRegion.SubOut(vibrantLightRegion); vibrantDarkRegion.SubOut(menuRegion); @@ -2403,18 +2401,16 @@ nsChildView::ClearVibrantAreas() } static VibrancyType -WidgetTypeToVibrancyType(uint8_t aWidgetType) +ThemeGeometryTypeToVibrancyType(nsITheme::ThemeGeometryType aThemeGeometryType) { - switch (aWidgetType) { - case NS_THEME_MAC_VIBRANCY_LIGHT: + switch (aThemeGeometryType) { + case nsNativeThemeCocoa::eThemeGeometryTypeVibrancyLight: return VibrancyType::LIGHT; - case NS_THEME_MAC_VIBRANCY_DARK: + case nsNativeThemeCocoa::eThemeGeometryTypeVibrancyDark: return VibrancyType::DARK; - case NS_THEME_TOOLTIP: + case nsNativeThemeCocoa::eThemeGeometryTypeTooltip: return VibrancyType::TOOLTIP; - case NS_THEME_MENUPOPUP: - case NS_THEME_MENUITEM: - case NS_THEME_CHECKMENUITEM: + case nsNativeThemeCocoa::eThemeGeometryTypeMenu: return VibrancyType::MENU; default: MOZ_CRASH(); @@ -2422,21 +2418,21 @@ WidgetTypeToVibrancyType(uint8_t aWidgetType) } NSColor* -nsChildView::VibrancyFillColorForWidgetType(uint8_t aWidgetType) +nsChildView::VibrancyFillColorForThemeGeometryType(nsITheme::ThemeGeometryType aThemeGeometryType) { if (VibrancyManager::SystemSupportsVibrancy()) { return EnsureVibrancyManager().VibrancyFillColorForType( - WidgetTypeToVibrancyType(aWidgetType)); + ThemeGeometryTypeToVibrancyType(aThemeGeometryType)); } return [NSColor whiteColor]; } NSColor* -nsChildView::VibrancyFontSmoothingBackgroundColorForWidgetType(uint8_t aWidgetType) +nsChildView::VibrancyFontSmoothingBackgroundColorForThemeGeometryType(nsITheme::ThemeGeometryType aThemeGeometryType) { if (VibrancyManager::SystemSupportsVibrancy()) { return EnsureVibrancyManager().VibrancyFontSmoothingBackgroundColorForType( - WidgetTypeToVibrancyType(aWidgetType)); + ThemeGeometryTypeToVibrancyType(aThemeGeometryType)); } return [NSColor clearColor]; } @@ -3256,20 +3252,20 @@ NSEvent* gLastDragMouseDownEvent = nil; [(BaseWindow*)[self window] drawsContentsIntoWindowFrame]; } -- (NSColor*)vibrancyFillColorForWidgetType:(uint8_t)aWidgetType +- (NSColor*)vibrancyFillColorForThemeGeometryType:(nsITheme::ThemeGeometryType)aThemeGeometryType { if (!mGeckoChild) { return [NSColor whiteColor]; } - return mGeckoChild->VibrancyFillColorForWidgetType(aWidgetType); + return mGeckoChild->VibrancyFillColorForThemeGeometryType(aThemeGeometryType); } -- (NSColor*)vibrancyFontSmoothingBackgroundColorForWidgetType:(uint8_t)aWidgetType +- (NSColor*)vibrancyFontSmoothingBackgroundColorForThemeGeometryType:(nsITheme::ThemeGeometryType)aThemeGeometryType { if (!mGeckoChild) { return [NSColor clearColor]; } - return mGeckoChild->VibrancyFontSmoothingBackgroundColorForWidgetType(aWidgetType); + return mGeckoChild->VibrancyFontSmoothingBackgroundColorForThemeGeometryType(aThemeGeometryType); } - (nsIntRegion)nativeDirtyRegionWithBoundingRect:(NSRect)aRect diff --git a/widget/cocoa/nsNativeThemeCocoa.h b/widget/cocoa/nsNativeThemeCocoa.h index 344d5db6d12b..4889f166ed4a 100644 --- a/widget/cocoa/nsNativeThemeCocoa.h +++ b/widget/cocoa/nsNativeThemeCocoa.h @@ -28,6 +28,18 @@ class nsNativeThemeCocoa : private nsNativeTheme, public nsITheme { public: + enum { + eThemeGeometryTypeTitlebar = eThemeGeometryTypeUnknown + 1, + eThemeGeometryTypeToolbar, + eThemeGeometryTypeWindowButtons, + eThemeGeometryTypeFullscreenButton, + eThemeGeometryTypeMenu, + eThemeGeometryTypeHighlightedMenuItem, + eThemeGeometryTypeVibrancyLight, + eThemeGeometryTypeVibrancyDark, + eThemeGeometryTypeTooltip, + }; + nsNativeThemeCocoa(); NS_DECL_ISUPPORTS_INHERITED @@ -65,6 +77,8 @@ public: virtual bool NeedToClearBackgroundBehindWidget(uint8_t aWidgetType) MOZ_OVERRIDE; virtual bool WidgetProvidesFontSmoothingBackgroundColor(nsIFrame* aFrame, uint8_t aWidgetType, nscolor* aColor) MOZ_OVERRIDE; + virtual ThemeGeometryType ThemeGeometryTypeForWidget(nsIFrame* aFrame, + uint8_t aWidgetType) MOZ_OVERRIDE; virtual Transparency GetWidgetTransparency(nsIFrame* aFrame, uint8_t aWidgetType) MOZ_OVERRIDE; void DrawProgress(CGContextRef context, const HIRect& inBoxRect, diff --git a/widget/cocoa/nsNativeThemeCocoa.mm b/widget/cocoa/nsNativeThemeCocoa.mm index 59e8614de95f..b005e22999b1 100644 --- a/widget/cocoa/nsNativeThemeCocoa.mm +++ b/widget/cocoa/nsNativeThemeCocoa.mm @@ -2256,7 +2256,7 @@ nsNativeThemeCocoa::DrawResizer(CGContextRef cgContext, const HIRect& aRect, static void DrawVibrancyBackground(CGContextRef cgContext, CGRect inBoxRect, - nsIFrame* aFrame, uint8_t aWidgetType, + nsIFrame* aFrame, nsITheme::ThemeGeometryType aThemeGeometryType, int aCornerRadius = 0) { ChildView* childView = ChildViewForFrame(aFrame); @@ -2270,7 +2270,7 @@ DrawVibrancyBackground(CGContextRef cgContext, CGRect inBoxRect, [[NSBezierPath bezierPathWithRoundedRect:rect xRadius:aCornerRadius yRadius:aCornerRadius] addClip]; } - [[childView vibrancyFillColorForWidgetType:aWidgetType] set]; + [[childView vibrancyFillColorForThemeGeometryType:aThemeGeometryType] set]; NSRectFill(rect); [NSGraphicsContext restoreGraphicsState]; @@ -2391,7 +2391,7 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext, case NS_THEME_MENUPOPUP: if (VibrancyManager::SystemSupportsVibrancy()) { - DrawVibrancyBackground(cgContext, macRect, aFrame, aWidgetType, 4); + DrawVibrancyBackground(cgContext, macRect, aFrame, eThemeGeometryTypeMenu, 4); } else { HIThemeMenuDrawInfo mdi; memset(&mdi, 0, sizeof(mdi)); @@ -2424,7 +2424,7 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext, bool isDisabled = IsDisabled(aFrame, eventState); bool isSelected = !isDisabled && CheckBooleanAttr(aFrame, nsGkAtoms::menuactive); if (!isSelected && VibrancyManager::SystemSupportsVibrancy()) { - DrawVibrancyBackground(cgContext, macRect, aFrame, aWidgetType); + DrawVibrancyBackground(cgContext, macRect, aFrame, eThemeGeometryTypeMenu); } else { // maybe use kThemeMenuItemHierBackground or PopUpBackground instead of just Plain? HIThemeMenuItemDrawInfo drawInfo; @@ -2472,7 +2472,7 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext, case NS_THEME_TOOLTIP: if (VibrancyManager::SystemSupportsVibrancy()) { - DrawVibrancyBackground(cgContext, macRect, aFrame, aWidgetType); + DrawVibrancyBackground(cgContext, macRect, aFrame, ThemeGeometryTypeForWidget(aFrame, aWidgetType)); } else { CGContextSetRGBFillColor(cgContext, 0.996, 1.000, 0.792, 0.950); CGContextFillRect(cgContext, macRect); @@ -2909,9 +2909,11 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext, break; case NS_THEME_MAC_VIBRANCY_LIGHT: - case NS_THEME_MAC_VIBRANCY_DARK: - DrawVibrancyBackground(cgContext, macRect, aFrame, aWidgetType); + case NS_THEME_MAC_VIBRANCY_DARK: { + ThemeGeometryType type = ThemeGeometryTypeForWidget(aFrame, aWidgetType); + DrawVibrancyBackground(cgContext, macRect, aFrame, type); break; + } } if (hidpi) { @@ -3793,7 +3795,8 @@ nsNativeThemeCocoa::WidgetProvidesFontSmoothingBackgroundColor(nsIFrame* aFrame, { ChildView* childView = ChildViewForFrame(aFrame); if (childView) { - NSColor* color = [childView vibrancyFontSmoothingBackgroundColorForWidgetType:aWidgetType]; + ThemeGeometryType type = ThemeGeometryTypeForWidget(aFrame, aWidgetType); + NSColor* color = [childView vibrancyFontSmoothingBackgroundColorForThemeGeometryType:type]; *aColor = ConvertNSColor(color); return true; } @@ -3804,6 +3807,34 @@ nsNativeThemeCocoa::WidgetProvidesFontSmoothingBackgroundColor(nsIFrame* aFrame, } } +nsITheme::ThemeGeometryType +nsNativeThemeCocoa::ThemeGeometryTypeForWidget(nsIFrame* aFrame, uint8_t aWidgetType) +{ + switch (aWidgetType) { + case NS_THEME_WINDOW_TITLEBAR: + return eThemeGeometryTypeTitlebar; + case NS_THEME_TOOLBAR: + case NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR: + return eThemeGeometryTypeToolbar; + case NS_THEME_WINDOW_BUTTON_BOX: + return eThemeGeometryTypeWindowButtons; + case NS_THEME_MOZ_MAC_FULLSCREEN_BUTTON: + return eThemeGeometryTypeFullscreenButton; + case NS_THEME_MAC_VIBRANCY_LIGHT: + return eThemeGeometryTypeVibrancyLight; + case NS_THEME_MAC_VIBRANCY_DARK: + return eThemeGeometryTypeVibrancyDark; + case NS_THEME_TOOLTIP: + return eThemeGeometryTypeTooltip; + case NS_THEME_MENUPOPUP: + case NS_THEME_MENUITEM: + case NS_THEME_CHECKMENUITEM: + return eThemeGeometryTypeMenu; + default: + return eThemeGeometryTypeUnknown; + } +} + nsITheme::Transparency nsNativeThemeCocoa::GetWidgetTransparency(nsIFrame* aFrame, uint8_t aWidgetType) { diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h index 2983a6158bb9..e1e09f8b5c32 100644 --- a/widget/nsIWidget.h +++ b/widget/nsIWidget.h @@ -15,6 +15,7 @@ #include "nsAutoPtr.h" #include "nsWidgetInitData.h" #include "nsTArray.h" +#include "nsITheme.h" #include "nsITimer.h" #include "nsXULAppAPI.h" #include "mozilla/EventForwards.h" @@ -740,14 +741,15 @@ class nsIWidget : public nsISupports { // Used in UpdateThemeGeometries. struct ThemeGeometry { - // The -moz-appearance value for the themed widget - uint8_t mWidgetType; + // The ThemeGeometryType value for the themed widget, see + // nsITheme::ThemeGeometryTypeForWidget. + nsITheme::ThemeGeometryType mType; // The device-pixel rect within the window for the themed widget nsIntRect mRect; - ThemeGeometry(uint8_t aWidgetType, const nsIntRect& aRect) - : mWidgetType(aWidgetType) - , mRect(aRect) + ThemeGeometry(nsITheme::ThemeGeometryType aType, const nsIntRect& aRect) + : mType(aType) + , mRect(aRect) { } }; diff --git a/widget/windows/nsNativeThemeWin.cpp b/widget/windows/nsNativeThemeWin.cpp index 51dc155e415e..a77ec5f04e88 100644 --- a/widget/windows/nsNativeThemeWin.cpp +++ b/widget/windows/nsNativeThemeWin.cpp @@ -2664,6 +2664,19 @@ nsNativeThemeWin::WidgetAppearanceDependsOnWindowFocus(uint8_t aWidgetType) } } +nsITheme::ThemeGeometryType +nsNativeThemeWin::ThemeGeometryTypeForWidget(nsIFrame* aFrame, + uint8_t aWidgetType) +{ + switch (aWidgetType) { + case NS_THEME_WINDOW_BUTTON_BOX: + case NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED: + return eThemeGeometryTypeWindowButtons; + default: + return eThemeGeometryTypeUnknown; + } +} + bool nsNativeThemeWin::ShouldHideScrollbars() { diff --git a/widget/windows/nsNativeThemeWin.h b/widget/windows/nsNativeThemeWin.h index 07ef3363d839..5c2672163ddb 100644 --- a/widget/windows/nsNativeThemeWin.h +++ b/widget/windows/nsNativeThemeWin.h @@ -74,6 +74,12 @@ public: virtual bool WidgetAppearanceDependsOnWindowFocus(uint8_t aWidgetType) MOZ_OVERRIDE; + enum { + eThemeGeometryTypeWindowButtons = eThemeGeometryTypeUnknown + 1 + }; + virtual ThemeGeometryType ThemeGeometryTypeForWidget(nsIFrame* aFrame, + uint8_t aWidgetType) MOZ_OVERRIDE; + virtual bool ShouldHideScrollbars() MOZ_OVERRIDE; nsNativeThemeWin(); diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index 46340afd430a..d9edbc9c464d 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -3531,8 +3531,7 @@ nsWindow::UpdateThemeGeometries(const nsTArray& aThemeGeometries) { nsIntRegion clearRegion; for (size_t i = 0; i < aThemeGeometries.Length(); i++) { - if ((aThemeGeometries[i].mWidgetType == NS_THEME_WINDOW_BUTTON_BOX || - aThemeGeometries[i].mWidgetType == NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED) && + if (aThemeGeometries[i].mType == nsNativeThemeWin::eThemeGeometryTypeWindowButtons && nsUXThemeData::CheckForCompositor()) { nsIntRect bounds = aThemeGeometries[i].mRect; From 81d520103dd7f7894e6bd50d351237707a5a5f35 Mon Sep 17 00:00:00 2001 From: Markus Stange Date: Wed, 4 Feb 2015 17:25:19 -0500 Subject: [PATCH 31/74] Bug 1045213 - Make the highlighted menu item vibrant. r=smichaud --- widget/cocoa/VibrancyManager.h | 3 ++- widget/cocoa/VibrancyManager.mm | 35 +++++++++++++++++++++++++----- widget/cocoa/nsChildView.mm | 9 ++++++++ widget/cocoa/nsNativeThemeCocoa.mm | 18 ++++++++++----- 4 files changed, 53 insertions(+), 12 deletions(-) diff --git a/widget/cocoa/VibrancyManager.h b/widget/cocoa/VibrancyManager.h index e8a8b6aba91a..c317f088ffa9 100644 --- a/widget/cocoa/VibrancyManager.h +++ b/widget/cocoa/VibrancyManager.h @@ -25,7 +25,8 @@ enum class VibrancyType { LIGHT, DARK, TOOLTIP, - MENU + MENU, + HIGHLIGHTED_MENUITEM }; /** diff --git a/widget/cocoa/VibrancyManager.mm b/widget/cocoa/VibrancyManager.mm index 25c35e60cf1b..2ace42d7ff3d 100644 --- a/widget/cocoa/VibrancyManager.mm +++ b/widget/cocoa/VibrancyManager.mm @@ -163,6 +163,7 @@ AppearanceForVibrancyType(VibrancyType aType) case VibrancyType::LIGHT: case VibrancyType::TOOLTIP: case VibrancyType::MENU: + case VibrancyType::HIGHLIGHTED_MENUITEM: return [NSAppearanceClass performSelector:@selector(appearanceNamed:) withObject:@"NSAppearanceNameVibrantLight"]; case VibrancyType::DARK: @@ -179,8 +180,29 @@ enum { }; #endif -@interface NSView(NSVisualEffectViewSetState) +static NSUInteger +VisualEffectStateForVibrancyType(VibrancyType aType) +{ + switch (aType) { + case VibrancyType::TOOLTIP: + case VibrancyType::MENU: + case VibrancyType::HIGHLIGHTED_MENUITEM: + // Tooltip and menu windows are never "key", so we need to tell the + // vibrancy effect to look active regardless of window state. + return NSVisualEffectStateActive; + default: + return NSVisualEffectStateFollowsWindowActiveState; + } +} + +enum { + NSVisualEffectMaterialMenuItem = 4 +}; + +@interface NSView(NSVisualEffectViewMethods) - (void)setState:(NSUInteger)state; +- (void)setMaterial:(NSUInteger)material; +- (void)setEmphasized:(BOOL)emphasized; @end NSView* @@ -190,10 +212,13 @@ VibrancyManager::CreateEffectView(VibrancyType aType, NSRect aRect) NSView* effectView = [[EffectViewClass alloc] initWithFrame:aRect]; [effectView performSelector:@selector(setAppearance:) withObject:AppearanceForVibrancyType(aType)]; - if (aType == VibrancyType::TOOLTIP || aType == VibrancyType::MENU) { - // Tooltip and menu windows never become active, so we need to tell the - // vibrancy effect to look active regardless of window state. - [effectView setState:NSVisualEffectStateActive]; + [effectView setState:VisualEffectStateForVibrancyType(aType)]; + + if (aType == VibrancyType::HIGHLIGHTED_MENUITEM) { + [effectView setMaterial:NSVisualEffectMaterialMenuItem]; + if ([effectView respondsToSelector:@selector(setEmphasized:)]) { + [effectView setEmphasized:YES]; + } } return effectView; } diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm index 9a9cf93678ae..02a5661ed1a0 100644 --- a/widget/cocoa/nsChildView.mm +++ b/widget/cocoa/nsChildView.mm @@ -2377,18 +2377,25 @@ nsChildView::UpdateVibrancy(const nsTArray& aThemeGeometries) GatherThemeGeometryRegion(aThemeGeometries, nsNativeThemeCocoa::eThemeGeometryTypeMenu); nsIntRegion tooltipRegion = GatherThemeGeometryRegion(aThemeGeometries, nsNativeThemeCocoa::eThemeGeometryTypeTooltip); + nsIntRegion highlightedMenuItemRegion = + GatherThemeGeometryRegion(aThemeGeometries, nsNativeThemeCocoa::eThemeGeometryTypeHighlightedMenuItem); vibrantDarkRegion.SubOut(vibrantLightRegion); vibrantDarkRegion.SubOut(menuRegion); vibrantDarkRegion.SubOut(tooltipRegion); + vibrantDarkRegion.SubOut(highlightedMenuItemRegion); vibrantLightRegion.SubOut(menuRegion); vibrantLightRegion.SubOut(tooltipRegion); + vibrantLightRegion.SubOut(highlightedMenuItemRegion); menuRegion.SubOut(tooltipRegion); + menuRegion.SubOut(highlightedMenuItemRegion); + tooltipRegion.SubOut(highlightedMenuItemRegion); auto& vm = EnsureVibrancyManager(); vm.UpdateVibrantRegion(VibrancyType::LIGHT, vibrantLightRegion); vm.UpdateVibrantRegion(VibrancyType::TOOLTIP, tooltipRegion); vm.UpdateVibrantRegion(VibrancyType::MENU, menuRegion); + vm.UpdateVibrantRegion(VibrancyType::HIGHLIGHTED_MENUITEM, highlightedMenuItemRegion); vm.UpdateVibrantRegion(VibrancyType::DARK, vibrantDarkRegion); } @@ -2412,6 +2419,8 @@ ThemeGeometryTypeToVibrancyType(nsITheme::ThemeGeometryType aThemeGeometryType) return VibrancyType::TOOLTIP; case nsNativeThemeCocoa::eThemeGeometryTypeMenu: return VibrancyType::MENU; + case nsNativeThemeCocoa::eThemeGeometryTypeHighlightedMenuItem: + return VibrancyType::HIGHLIGHTED_MENUITEM; default: MOZ_CRASH(); } diff --git a/widget/cocoa/nsNativeThemeCocoa.mm b/widget/cocoa/nsNativeThemeCocoa.mm index b005e22999b1..97e82921e6be 100644 --- a/widget/cocoa/nsNativeThemeCocoa.mm +++ b/widget/cocoa/nsNativeThemeCocoa.mm @@ -2421,11 +2421,12 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext, case NS_THEME_MENUITEM: case NS_THEME_CHECKMENUITEM: { - bool isDisabled = IsDisabled(aFrame, eventState); - bool isSelected = !isDisabled && CheckBooleanAttr(aFrame, nsGkAtoms::menuactive); - if (!isSelected && VibrancyManager::SystemSupportsVibrancy()) { - DrawVibrancyBackground(cgContext, macRect, aFrame, eThemeGeometryTypeMenu); + if (VibrancyManager::SystemSupportsVibrancy()) { + ThemeGeometryType type = ThemeGeometryTypeForWidget(aFrame, aWidgetType); + DrawVibrancyBackground(cgContext, macRect, aFrame, type); } else { + bool isDisabled = IsDisabled(aFrame, eventState); + bool isSelected = !isDisabled && CheckBooleanAttr(aFrame, nsGkAtoms::menuactive); // maybe use kThemeMenuItemHierBackground or PopUpBackground instead of just Plain? HIThemeMenuItemDrawInfo drawInfo; memset(&drawInfo, 0, sizeof(drawInfo)); @@ -3827,9 +3828,14 @@ nsNativeThemeCocoa::ThemeGeometryTypeForWidget(nsIFrame* aFrame, uint8_t aWidget case NS_THEME_TOOLTIP: return eThemeGeometryTypeTooltip; case NS_THEME_MENUPOPUP: - case NS_THEME_MENUITEM: - case NS_THEME_CHECKMENUITEM: return eThemeGeometryTypeMenu; + case NS_THEME_MENUITEM: + case NS_THEME_CHECKMENUITEM: { + EventStates eventState = GetContentState(aFrame, aWidgetType); + bool isDisabled = IsDisabled(aFrame, eventState); + bool isSelected = !isDisabled && CheckBooleanAttr(aFrame, nsGkAtoms::menuactive); + return isSelected ? eThemeGeometryTypeHighlightedMenuItem : eThemeGeometryTypeMenu; + } default: return eThemeGeometryTypeUnknown; } From 61101209ee4f96d2987c927499986b3052a085b6 Mon Sep 17 00:00:00 2001 From: Markus Stange Date: Wed, 4 Feb 2015 17:25:19 -0500 Subject: [PATCH 32/74] Bug 1045213 - Get smooth rounded corners for vibrant context menus by using _cornerMask. r=smichaud --- widget/cocoa/nsCocoaWindow.h | 10 ++++++ widget/cocoa/nsCocoaWindow.mm | 57 ++++++++++++++++++++++++++++++ widget/cocoa/nsNativeThemeCocoa.mm | 11 ++---- 3 files changed, 69 insertions(+), 9 deletions(-) diff --git a/widget/cocoa/nsCocoaWindow.h b/widget/cocoa/nsCocoaWindow.h index 530f05c4a58d..ebee588d380d 100644 --- a/widget/cocoa/nsCocoaWindow.h +++ b/widget/cocoa/nsCocoaWindow.h @@ -41,6 +41,13 @@ typedef NSInteger NSWindowAnimationBehavior; - (void)toggleFullScreen:(id)sender; @end +typedef struct NSEdgeInsets { + CGFloat top; + CGFloat left; + CGFloat bottom; + CGFloat right; +} NSEdgeInsets; + #endif typedef struct _nsCocoaWindowList { @@ -82,6 +89,7 @@ typedef struct _nsCocoaWindowList { BOOL mBeingShown; BOOL mDrawTitle; BOOL mBrightTitlebarForeground; + BOOL mUseMenuStyle; } - (void)importState:(NSDictionary*)aState; @@ -120,6 +128,8 @@ typedef struct _nsCocoaWindowList { - (NSRect)getAndResetNativeDirtyRect; +- (void)setUseMenuStyle:(BOOL)aValue; + @end @interface NSWindow (Undocumented) diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm index 1dc2a788064b..254f6a0db276 100644 --- a/widget/cocoa/nsCocoaWindow.mm +++ b/widget/cocoa/nsCocoaWindow.mm @@ -1931,6 +1931,7 @@ NS_IMETHODIMP nsCocoaWindow::SetWindowShadowStyle(int32_t aStyle) mShadowStyle = aStyle; [mWindow setHasShadow:(aStyle != NS_STYLE_WINDOW_SHADOW_NONE)]; + [mWindow setUseMenuStyle:(aStyle == NS_STYLE_WINDOW_SHADOW_MENU)]; AdjustWindowShadow(); SetWindowBackgroundBlur(); @@ -2592,6 +2593,32 @@ static NSMutableSet *gSwizzledFrameViewClasses = nil; - (void)_addKnownSubview:(NSView*)aView positioned:(NSWindowOrderingMode)place relativeTo:(NSView*)otherView; @end +// Available on 10.10 +@interface NSWindow(PrivateCornerMaskMethod) + - (id)_cornerMask; + - (void)_cornerMaskChanged; +@end + +#if !defined(MAC_OS_X_VERSION_10_10) || \ + MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_10 + +@interface NSImage(CapInsets) +- (void)setCapInsets:(NSEdgeInsets)capInsets; +@end + +#endif + +#if !defined(MAC_OS_X_VERSION_10_8) || \ + MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_8 + +@interface NSImage(ImageCreationWithDrawingHandler) ++ (NSImage *)imageWithSize:(NSSize)size + flipped:(BOOL)drawingHandlerShouldBeCalledWithFlippedContext + drawingHandler:(BOOL (^)(NSRect dstRect))drawingHandler; +@end + +#endif + @interface BaseWindow(Private) - (void)removeTrackingArea; - (void)cursorUpdated:(NSEvent*)aEvent; @@ -2601,6 +2628,25 @@ static NSMutableSet *gSwizzledFrameViewClasses = nil; @implementation BaseWindow +- (id)_cornerMask +{ + if (!mUseMenuStyle) { + return [super _cornerMask]; + } + + CGFloat radius = 4.0f; + NSEdgeInsets insets = { 5, 5, 5, 5 }; + NSSize maskSize = { 12, 12 }; + NSImage* maskImage = [NSImage imageWithSize:maskSize flipped:YES drawingHandler:^BOOL(NSRect dstRect) { + NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:dstRect xRadius:radius yRadius:radius]; + [[NSColor colorWithDeviceWhite:1.0 alpha:1.0] set]; + [path fill]; + return YES; + }]; + [maskImage setCapInsets:insets]; + return maskImage; +} + // The frame of a window is implemented using undocumented NSView subclasses. // We offset the window buttons by overriding the methods _closeButtonOrigin // and _fullScreenButtonOrigin on these frame view classes. The class which is @@ -2667,11 +2713,22 @@ static NSMutableSet *gSwizzledFrameViewClasses = nil; mBeingShown = NO; mDrawTitle = NO; mBrightTitlebarForeground = NO; + mUseMenuStyle = NO; [self updateTrackingArea]; return self; } +- (void)setUseMenuStyle:(BOOL)aValue +{ + if (aValue != mUseMenuStyle) { + mUseMenuStyle = aValue; + if ([self respondsToSelector:@selector(_cornerMaskChanged)]) { + [self _cornerMaskChanged]; + } + } +} + - (void)setBeingShown:(BOOL)aValue { mBeingShown = aValue; diff --git a/widget/cocoa/nsNativeThemeCocoa.mm b/widget/cocoa/nsNativeThemeCocoa.mm index 97e82921e6be..893d10c1486c 100644 --- a/widget/cocoa/nsNativeThemeCocoa.mm +++ b/widget/cocoa/nsNativeThemeCocoa.mm @@ -2256,24 +2256,17 @@ nsNativeThemeCocoa::DrawResizer(CGContextRef cgContext, const HIRect& aRect, static void DrawVibrancyBackground(CGContextRef cgContext, CGRect inBoxRect, - nsIFrame* aFrame, nsITheme::ThemeGeometryType aThemeGeometryType, - int aCornerRadius = 0) + nsIFrame* aFrame, nsITheme::ThemeGeometryType aThemeGeometryType) { ChildView* childView = ChildViewForFrame(aFrame); if (childView) { NSRect rect = NSRectFromCGRect(inBoxRect); NSGraphicsContext* savedContext = [NSGraphicsContext currentContext]; [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:cgContext flipped:YES]]; - [NSGraphicsContext saveGraphicsState]; - - if (aCornerRadius > 0) { - [[NSBezierPath bezierPathWithRoundedRect:rect xRadius:aCornerRadius yRadius:aCornerRadius] addClip]; - } [[childView vibrancyFillColorForThemeGeometryType:aThemeGeometryType] set]; NSRectFill(rect); - [NSGraphicsContext restoreGraphicsState]; [NSGraphicsContext setCurrentContext:savedContext]; } } @@ -2391,7 +2384,7 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext, case NS_THEME_MENUPOPUP: if (VibrancyManager::SystemSupportsVibrancy()) { - DrawVibrancyBackground(cgContext, macRect, aFrame, eThemeGeometryTypeMenu, 4); + DrawVibrancyBackground(cgContext, macRect, aFrame, eThemeGeometryTypeMenu); } else { HIThemeMenuDrawInfo mdi; memset(&mdi, 0, sizeof(mdi)); From 3edb5567119c32b6a4b6f09abb48ad8b69de8b61 Mon Sep 17 00:00:00 2001 From: Markus Stange Date: Wed, 4 Feb 2015 17:25:19 -0500 Subject: [PATCH 33/74] Bug 1045213 - Add a MakeRegionsNonOverlapping function for less repetitive code. r=botond --- widget/cocoa/nsChildView.mm | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm index 02a5661ed1a0..b5fa1e3f5945 100644 --- a/widget/cocoa/nsChildView.mm +++ b/widget/cocoa/nsChildView.mm @@ -2362,6 +2362,28 @@ GatherThemeGeometryRegion(const nsTArray& aThemeGeomet return region; } +template +static void MakeRegionsNonOverlappingImpl(T& aOutUnion) { } + +template +static void MakeRegionsNonOverlappingImpl(T& aOutUnion, T& aFirst, TT& ... aRest) +{ + MakeRegionsNonOverlappingImpl(aOutUnion, aRest...); + aFirst.SubOut(aOutUnion); + aOutUnion.OrWith(aFirst); +} + +// Subtracts parts from regions in such a way that they don't have any overlap. +// Each region in the argument list will have the union of all the regions +// *following* it subtracted from itself. In other words, the arguments are +// sorted low priority to high priority. +template +static void MakeRegionsNonOverlapping(T& aFirst, TT& ... aRest) +{ + T unionOfAll; + MakeRegionsNonOverlappingImpl(unionOfAll, aFirst, aRest...); +} + void nsChildView::UpdateVibrancy(const nsTArray& aThemeGeometries) { @@ -2380,16 +2402,8 @@ nsChildView::UpdateVibrancy(const nsTArray& aThemeGeometries) nsIntRegion highlightedMenuItemRegion = GatherThemeGeometryRegion(aThemeGeometries, nsNativeThemeCocoa::eThemeGeometryTypeHighlightedMenuItem); - vibrantDarkRegion.SubOut(vibrantLightRegion); - vibrantDarkRegion.SubOut(menuRegion); - vibrantDarkRegion.SubOut(tooltipRegion); - vibrantDarkRegion.SubOut(highlightedMenuItemRegion); - vibrantLightRegion.SubOut(menuRegion); - vibrantLightRegion.SubOut(tooltipRegion); - vibrantLightRegion.SubOut(highlightedMenuItemRegion); - menuRegion.SubOut(tooltipRegion); - menuRegion.SubOut(highlightedMenuItemRegion); - tooltipRegion.SubOut(highlightedMenuItemRegion); + MakeRegionsNonOverlapping(vibrantLightRegion, vibrantDarkRegion, menuRegion, + tooltipRegion, highlightedMenuItemRegion); auto& vm = EnsureVibrancyManager(); vm.UpdateVibrantRegion(VibrancyType::LIGHT, vibrantLightRegion); From c9764ae72386656753fe1ecfebee100301a182a5 Mon Sep 17 00:00:00 2001 From: Markus Stange Date: Wed, 4 Feb 2015 17:25:19 -0500 Subject: [PATCH 34/74] Bug 1045213 - Make menu separators look correct by having them use foreground vibrancy. r=smichaud --- widget/cocoa/VibrancyManager.mm | 49 ++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/widget/cocoa/VibrancyManager.mm b/widget/cocoa/VibrancyManager.mm index 2ace42d7ff3d..95e914cfc603 100644 --- a/widget/cocoa/VibrancyManager.mm +++ b/widget/cocoa/VibrancyManager.mm @@ -140,18 +140,31 @@ HitTestNil(id self, SEL _cmd, NSPoint aPoint) return nil; } +static BOOL +AllowsVibrancyYes(id self, SEL _cmd) +{ + // Means that the foreground is blended using a vibrant blend mode. + return YES; +} + static Class -CreateEffectViewClass() +CreateEffectViewClass(BOOL aForegroundVibrancy) { // Create a class called EffectView that inherits from NSVisualEffectView // and overrides the methods -[NSVisualEffectView drawRect:] and // -[NSView hitTest:]. Class NSVisualEffectViewClass = NSClassFromString(@"NSVisualEffectView"); - Class EffectViewClass = objc_allocateClassPair(NSVisualEffectViewClass, "EffectView", 0); + const char* className = aForegroundVibrancy + ? "EffectViewWithForegroundVibrancy" : "EffectViewWithoutForegroundVibrancy"; + Class EffectViewClass = objc_allocateClassPair(NSVisualEffectViewClass, className, 0); class_addMethod(EffectViewClass, @selector(drawRect:), (IMP)DrawRectNothing, "v@:{CGRect={CGPoint=dd}{CGSize=dd}}"); class_addMethod(EffectViewClass, @selector(hitTest:), (IMP)HitTestNil, "@@:{CGPoint=dd}"); + if (aForegroundVibrancy) { + // Also override the -[NSView allowsVibrancy] method to return YES. + class_addMethod(EffectViewClass, @selector(allowsVibrancy), (IMP)AllowsVibrancyYes, "I@:"); + } return EffectViewClass; } @@ -178,6 +191,10 @@ enum { NSVisualEffectStateActive, NSVisualEffectStateInactive }; + +enum { + NSVisualEffectMaterialTitlebar = 3 +}; #endif static NSUInteger @@ -195,6 +212,17 @@ VisualEffectStateForVibrancyType(VibrancyType aType) } } +static BOOL +HasVibrantForeground(VibrancyType aType) +{ + switch (aType) { + case VibrancyType::MENU: + return YES; + default: + return NO; + } +} + enum { NSVisualEffectMaterialMenuItem = 4 }; @@ -208,18 +236,31 @@ enum { NSView* VibrancyManager::CreateEffectView(VibrancyType aType, NSRect aRect) { - static Class EffectViewClass = CreateEffectViewClass(); + static Class EffectViewClassWithoutForegroundVibrancy = CreateEffectViewClass(NO); + static Class EffectViewClassWithForegroundVibrancy = CreateEffectViewClass(YES); + + Class EffectViewClass = HasVibrantForeground(aType) + ? EffectViewClassWithForegroundVibrancy : EffectViewClassWithoutForegroundVibrancy; NSView* effectView = [[EffectViewClass alloc] initWithFrame:aRect]; [effectView performSelector:@selector(setAppearance:) withObject:AppearanceForVibrancyType(aType)]; [effectView setState:VisualEffectStateForVibrancyType(aType)]; - if (aType == VibrancyType::HIGHLIGHTED_MENUITEM) { + if (aType == VibrancyType::MENU) { + // NSVisualEffectMaterialTitlebar doesn't match the native menu look + // perfectly but comes pretty close. Ideally we'd use a material with + // materialTypeName "MacLight", since that's what menus use, but there's + // no entry with that material in the internalMaterialType-to- + // CGSWindowBackdropViewSpec table which NSVisualEffectView consults when + // setting up the effect. + [effectView setMaterial:NSVisualEffectMaterialTitlebar]; + } else if (aType == VibrancyType::HIGHLIGHTED_MENUITEM) { [effectView setMaterial:NSVisualEffectMaterialMenuItem]; if ([effectView respondsToSelector:@selector(setEmphasized:)]) { [effectView setEmphasized:YES]; } } + return effectView; } From 2438e023a84bd33d14f40f734072283dcdb98f24 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sun, 1 Feb 2015 14:56:33 -0800 Subject: [PATCH 35/74] Bug 1050035 (part 1) - Lazily allocate PLDHashTable::mEntryStore. r=froydnj. This makes zero-element hash tables, which are common, smaller, and also avoids unnecessary malloc/free pairs. I did some measurements during some basic browsing of a few sites. I found that 35% of all live tables were empty with a few tabs open. And cumulatively, for the whole session, 45% of tables never had an element added to them. There is more to be done w.r.t. simplifying initialization, which will occur in the next patch. --HG-- extra : rebase_source : b9bfdcd680f39f3c947a49ae8462c04bc5e38805 --- xpcom/glue/pldhash.cpp | 46 +++++++++++++++++++------ xpcom/glue/pldhash.h | 31 +++++++++++------ xpcom/tests/TestPLDHash.cpp | 68 ++++++++++++++++++++++++++++++++++--- 3 files changed, 120 insertions(+), 25 deletions(-) diff --git a/xpcom/glue/pldhash.cpp b/xpcom/glue/pldhash.cpp index 7090a0661add..b6f93fd3b3ea 100644 --- a/xpcom/glue/pldhash.cpp +++ b/xpcom/glue/pldhash.cpp @@ -247,11 +247,8 @@ PLDHashTable::Init(const PLDHashTableOps* aOps, return false; // overflowed } - mEntryStore = (char*)malloc(nbytes); - if (!mEntryStore) { - return false; - } - memset(mEntryStore, 0, nbytes); + mEntryStore = nullptr; + METER(memset(&mStats, 0, sizeof(mStats))); // Set this only once we reach a point where we know we can't fail. @@ -348,6 +345,7 @@ PLDHashTable::Finish() /* Free entry storage last. */ free(mEntryStore); + mEntryStore = nullptr; } void @@ -365,6 +363,7 @@ template PLDHashEntryHdr* PL_DHASH_FASTCALL PLDHashTable::SearchTable(const void* aKey, PLDHashNumber aKeyHash) { + MOZ_ASSERT(mEntryStore); METER(mStats.mSearches++); NS_ASSERTION(!(aKeyHash & COLLISION_FLAG), "!(aKeyHash & COLLISION_FLAG)"); @@ -445,6 +444,7 @@ PLDHashEntryHdr* PL_DHASH_FASTCALL PLDHashTable::FindFreeEntry(PLDHashNumber aKeyHash) { METER(mStats.mSearches++); + MOZ_ASSERT(mEntryStore); NS_ASSERTION(!(aKeyHash & COLLISION_FLAG), "!(aKeyHash & COLLISION_FLAG)"); @@ -486,6 +486,8 @@ PLDHashTable::FindFreeEntry(PLDHashNumber aKeyHash) bool PLDHashTable::ChangeTable(int aDeltaLog2) { + MOZ_ASSERT(mEntryStore); + /* Look, but don't touch, until we succeed in getting new entry store. */ int oldLog2 = PL_DHASH_BITS - mHashShift; int newLog2 = oldLog2 + aDeltaLog2; @@ -561,8 +563,9 @@ PLDHashTable::Search(const void* aKey) METER(mStats.mSearches++); - PLDHashNumber keyHash = ComputeKeyHash(aKey); - PLDHashEntryHdr* entry = SearchTable(aKey, keyHash); + PLDHashEntryHdr* entry = + mEntryStore ? SearchTable(aKey, ComputeKeyHash(aKey)) + : nullptr; DECREMENT_RECURSION_LEVEL(this); @@ -574,16 +577,29 @@ PLDHashTable::Add(const void* aKey) { PLDHashNumber keyHash; PLDHashEntryHdr* entry; + uint32_t capacity; MOZ_ASSERT(mRecursionLevel == 0); INCREMENT_RECURSION_LEVEL(this); + // Allocate the entry storage if it hasn't already been allocated. + if (!mEntryStore) { + uint32_t nbytes; + if (!SizeOfEntryStore(CapacityFromHashShift(), mEntrySize, &nbytes) || + !(mEntryStore = (char*)malloc(nbytes))) { + METER(mStats.mAddFailures++); + entry = nullptr; + goto exit; + } + memset(mEntryStore, 0, nbytes); + } + /* * If alpha is >= .75, grow or compress the table. If aKey is already * in the table, we may grow once more than necessary, but only if we * are on the edge of being overloaded. */ - uint32_t capacity = Capacity(); + capacity = Capacity(); if (mEntryCount + mRemovedCount >= MaxLoad(capacity)) { /* Compress if a quarter or more of all entries are removed. */ int deltaLog2; @@ -613,7 +629,7 @@ PLDHashTable::Add(const void* aKey) * then skip it while growing the table and re-add it after. */ keyHash = ComputeKeyHash(aKey); - entry = SearchTable(aKey, keyHash); + entry = mEntryStore ? SearchTable(aKey, keyHash) : nullptr; if (!ENTRY_IS_LIVE(entry)) { /* Initialize the entry, indicating that it's no longer free. */ METER(mStats.mAddMisses++); @@ -646,8 +662,9 @@ PLDHashTable::Remove(const void* aKey) MOZ_ASSERT(mRecursionLevel == 0); INCREMENT_RECURSION_LEVEL(this); - PLDHashNumber keyHash = ComputeKeyHash(aKey); - PLDHashEntryHdr* entry = SearchTable(aKey, keyHash); + PLDHashEntryHdr* entry = + mEntryStore ? SearchTable(aKey, ComputeKeyHash(aKey)) + : nullptr; if (entry) { /* Clear this entry and mark it as "removed". */ METER(mStats.mRemoveHits++); @@ -736,6 +753,7 @@ PLDHashTable::Enumerate(PLDHashEnumerator aEtor, void* aArg) } } + MOZ_ASSERT_IF(capacity > 0, mEntryStore); for (uint32_t e = 0; e < capacity; ++e) { PLDHashEntryHdr* entry = (PLDHashEntryHdr*)entryAddr; if (ENTRY_IS_LIVE(entry)) { @@ -815,6 +833,10 @@ PLDHashTable::SizeOfExcludingThis( PLDHashSizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis, MallocSizeOf aMallocSizeOf, void* aArg /* = nullptr */) const { + if (!mEntryStore) { + return 0; + } + size_t n = 0; n += aMallocSizeOf(mEntryStore); if (aSizeOfEntryExcludingThis) { @@ -927,6 +949,7 @@ PLDHashEntryHdr* PLDHashTable::Iterator::NextEntry() // checks pass, then this method will only iterate through the full capacity // once. If they fail, then this loop may end up returning the early entries // more than once. + MOZ_ASSERT_IF(capacity > 0, mTable->mEntryStore); for (uint32_t e = 0; e < capacity; ++e) { PLDHashEntryHdr* entry = (PLDHashEntryHdr*)mEntryAddr; @@ -980,6 +1003,7 @@ PLDHashTable::DumpMeter(PLDHashEnumerator aDump, FILE* aFp) hash2 = 0; sqsum = 0; + MOZ_ASSERT_IF(capacity > 0, mEntryStore); for (uint32_t i = 0; i < capacity; i++) { entry = (PLDHashEntryHdr*)entryAddr; entryAddr += mEntrySize; diff --git a/xpcom/glue/pldhash.h b/xpcom/glue/pldhash.h index 3090ac5dfc70..0660ee103e5a 100644 --- a/xpcom/glue/pldhash.h +++ b/xpcom/glue/pldhash.h @@ -147,6 +147,9 @@ typedef size_t (*PLDHashSizeOfEntryExcludingThisFun)( * on most architectures, and may be allocated on the stack or within another * structure or class (see below for the Init and Finish functions to use). * + * No entry storage is allocated until the first element is added. This means + * that empty hash tables are cheap, which is good because they are common. + * * There used to be a long, math-heavy comment here about the merits of * double hashing vs. chaining; it was removed in bug 1058335. In short, double * hashing is more space-efficient unless the element size gets large (in which @@ -175,8 +178,7 @@ private: uint32_t mEntryCount; /* number of entries in table */ uint32_t mRemovedCount; /* removed entry sentinels in table */ uint32_t mGeneration; /* entry storage generation number */ - char* mEntryStore; /* entry storage */ - + char* mEntryStore; /* entry storage; allocated lazily */ #ifdef PL_DHASHMETER struct PLDHashStats { @@ -226,12 +228,12 @@ public: /* * Size in entries (gross, not net of free and removed sentinels) for table. - * We store mHashShift rather than sizeLog2 to optimize the collision-free - * case in SearchTable. + * This can be zero if no elements have been added yet, in which case the + * entry storage will not have yet been allocated. */ uint32_t Capacity() const { - return ((uint32_t)1 << (PL_DHASH_BITS - mHashShift)); + return mEntryStore ? CapacityFromHashShift() : 0; } uint32_t EntrySize() const { return mEntrySize; } @@ -297,6 +299,13 @@ public: private: static bool EntryIsFree(PLDHashEntryHdr* aEntry); + // We store mHashShift rather than sizeLog2 to optimize the collision-free + // case in SearchTable. + uint32_t CapacityFromHashShift() const + { + return ((uint32_t)1 << (PL_DHASH_BITS - mHashShift)); + } + PLDHashNumber ComputeKeyHash(const void* aKey); enum SearchReason { ForSearchOrRemove, ForAdd }; @@ -441,12 +450,14 @@ PLDHashTable* PL_NewDHashTable( void PL_DHashTableDestroy(PLDHashTable* aTable); /* - * Initialize aTable with aOps, aEntrySize, and aCapacity. The table's initial - * capacity will be chosen such that |aLength| elements can be inserted without - * rehashing. If |aLength| is a power-of-two, this capacity will be |2*length|. + * Initialize aTable with aOps and aEntrySize. The table's initial capacity + * will be chosen such that |aLength| elements can be inserted without + * rehashing; if |aLength| is a power-of-two, this capacity will be |2*length|. + * However, because entry storage is allocated lazily, this initial capacity + * won't be relevant until the first element is added; prior to that the + * capacity will be zero. * - * This function will crash if it can't allocate enough memory, or if - * |aEntrySize| and/or |aLength| are too large. + * This function will crash if |aEntrySize| and/or |aLength| are too large. */ void PL_DHashTableInit( PLDHashTable* aTable, const PLDHashTableOps* aOps, diff --git a/xpcom/tests/TestPLDHash.cpp b/xpcom/tests/TestPLDHash.cpp index fdb6ea5bbfef..9d14d16791e4 100644 --- a/xpcom/tests/TestPLDHash.cpp +++ b/xpcom/tests/TestPLDHash.cpp @@ -7,10 +7,8 @@ #include #include "pldhash.h" -// pldhash is very widely used and so any basic bugs in it are likely to be -// exposed through normal usage. Therefore, this test currently focusses on -// extreme cases relating to maximum table capacity and potential overflows, -// which are unlikely to be hit during normal execution. +// This test mostly focuses on edge cases. But more coverage of normal +// operations wouldn't be a bad thing. namespace TestPLDHash { @@ -106,6 +104,67 @@ static bool test_pldhash_Init_overflow() return true; } +static bool test_pldhash_lazy_storage() +{ + PLDHashTable t; + PL_DHashTableInit(&t, PL_DHashGetStubOps(), sizeof(PLDHashEntryStub)); + + // PLDHashTable allocates entry storage lazily. Check that all the non-add + // operations work appropriately when the table is empty and the storage + // hasn't yet been allocated. + + if (!t.IsInitialized()) { + return false; + } + + if (t.Capacity() != 0) { + return false; + } + + if (t.EntrySize() != sizeof(PLDHashEntryStub)) { + return false; + } + + if (t.EntryCount() != 0) { + return false; + } + + if (t.Generation() != 0) { + return false; + } + + if (PL_DHashTableSearch(&t, (const void*)1)) { + return false; // search succeeded? + } + + // No result to check here, but call it to make sure it doesn't crash. + PL_DHashTableRemove(&t, (const void*)2); + + // Using a null |enumerator| should be fine because it shouldn't be called + // for an empty table. + PLDHashEnumerator enumerator = nullptr; + if (PL_DHashTableEnumerate(&t, enumerator, nullptr) != 0) { + return false; // enumeration count is non-zero? + } + + for (PLDHashTable::Iterator iter = t.Iterate(); + iter.HasMoreEntries(); + iter.NextEntry()) { + return false; // shouldn't hit this on an empty table + } + + // Using a null |mallocSizeOf| should be fine because it shouldn't be called + // for an empty table. + mozilla::MallocSizeOf mallocSizeOf = nullptr; + if (PL_DHashTableSizeOfExcludingThis(&t, nullptr, mallocSizeOf) != 0) { + return false; // size is non-zero? + } + + PL_DHashTableFinish(&t); + + return true; +} + // See bug 931062, we skip this test on Android due to OOM. #ifndef MOZ_WIDGET_ANDROID // We insert the integers 0.., so this is has function is (a) as simple as @@ -168,6 +227,7 @@ static const struct Test { DECL_TEST(test_pldhash_Init_capacity_ok), DECL_TEST(test_pldhash_Init_capacity_too_large), DECL_TEST(test_pldhash_Init_overflow), + DECL_TEST(test_pldhash_lazy_storage), // See bug 931062, we skip this test on Android due to OOM. #ifndef MOZ_WIDGET_ANDROID DECL_TEST(test_pldhash_grow_to_max_capacity), From 9a36fdbde42d45faddbe9996c4682ec9e7cb8a81 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sun, 1 Feb 2015 20:19:08 -0800 Subject: [PATCH 36/74] Bug 1050035 (part 2) - Remove the fallible version of PL_DHashTableInit(). r=froydnj,mrbkap. Because it's no longer needed now that entry storage isn't allocated there. (The other possible causes of failures are much less interesting and simply crashing is a reasonable thing to do for them.) This also makes PL_DNewHashTable() infallible. --HG-- extra : rebase_source : 848cc9bbdfe434525857183b8370d309f3acbf49 --- dom/base/nsDocument.cpp | 3 - dom/base/nsScriptNameSpaceManager.cpp | 31 +++----- dom/base/nsScriptNameSpaceManager.h | 2 - dom/xul/XULDocument.cpp | 5 -- js/xpconnect/src/XPCJSRuntime.cpp | 87 ++++++++------------- js/xpconnect/src/XPCMaps.cpp | 100 ++++++------------------ js/xpconnect/src/XPCMaps.h | 2 +- layout/style/nsRuleNode.cpp | 2 - modules/libpref/Preferences.cpp | 6 +- modules/libpref/prefapi.cpp | 11 +-- modules/libpref/prefapi.h | 2 +- netwerk/cache/nsCacheEntry.cpp | 38 ++++----- netwerk/cache/nsCacheEntry.h | 3 +- netwerk/cache/nsCacheService.cpp | 3 +- netwerk/cache/nsMemoryCacheDevice.cpp | 6 +- netwerk/protocol/http/nsHttp.cpp | 6 +- parser/htmlparser/nsHTMLEntities.cpp | 15 +--- security/manager/ssl/src/nsCertTree.cpp | 24 +++--- security/manager/ssl/src/nsCertTree.h | 2 +- xpcom/ds/nsStaticNameTable.cpp | 7 +- xpcom/glue/pldhash.cpp | 46 +++-------- xpcom/glue/pldhash.h | 15 +--- xpcom/tests/TestPLDHash.cpp | 83 ++++---------------- 23 files changed, 137 insertions(+), 362 deletions(-) diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 265ba6a6370d..213697bd58da 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -3985,9 +3985,6 @@ nsDocument::SetSubDocumentFor(Element* aElement, nsIDocument* aSubDoc) }; mSubDocuments = PL_NewDHashTable(&hash_table_ops, sizeof(SubDocMapEntry)); - if (!mSubDocuments) { - return NS_ERROR_OUT_OF_MEMORY; - } } // Add a mapping to the hash table diff --git a/dom/base/nsScriptNameSpaceManager.cpp b/dom/base/nsScriptNameSpaceManager.cpp index d4b935fda173..eab3042bfbc8 100644 --- a/dom/base/nsScriptNameSpaceManager.cpp +++ b/dom/base/nsScriptNameSpaceManager.cpp @@ -122,19 +122,16 @@ NS_IMPL_ISUPPORTS( nsIMemoryReporter) nsScriptNameSpaceManager::nsScriptNameSpaceManager() - : mIsInitialized(false) { MOZ_COUNT_CTOR(nsScriptNameSpaceManager); } nsScriptNameSpaceManager::~nsScriptNameSpaceManager() { - if (mIsInitialized) { - UnregisterWeakMemoryReporter(this); - // Destroy the hash - PL_DHashTableFinish(&mGlobalNames); - PL_DHashTableFinish(&mNavigatorNames); - } + UnregisterWeakMemoryReporter(this); + // Destroy the hash + PL_DHashTableFinish(&mGlobalNames); + PL_DHashTableFinish(&mNavigatorNames); MOZ_COUNT_DTOR(nsScriptNameSpaceManager); } @@ -326,21 +323,13 @@ nsScriptNameSpaceManager::Init() GlobalNameHashInitEntry }; - mIsInitialized = PL_DHashTableInit(&mGlobalNames, &hash_table_ops, - sizeof(GlobalNameMapEntry), - fallible, - GLOBALNAME_HASHTABLE_INITIAL_LENGTH); - NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_OUT_OF_MEMORY); + PL_DHashTableInit(&mGlobalNames, &hash_table_ops, + sizeof(GlobalNameMapEntry), + GLOBALNAME_HASHTABLE_INITIAL_LENGTH); - mIsInitialized = PL_DHashTableInit(&mNavigatorNames, &hash_table_ops, - sizeof(GlobalNameMapEntry), - fallible, - GLOBALNAME_HASHTABLE_INITIAL_LENGTH); - if (!mIsInitialized) { - PL_DHashTableFinish(&mGlobalNames); - - return NS_ERROR_OUT_OF_MEMORY; - } + PL_DHashTableInit(&mNavigatorNames, &hash_table_ops, + sizeof(GlobalNameMapEntry), + GLOBALNAME_HASHTABLE_INITIAL_LENGTH); RegisterWeakMemoryReporter(this); diff --git a/dom/base/nsScriptNameSpaceManager.h b/dom/base/nsScriptNameSpaceManager.h index b59f4849b388..667d747e1253 100644 --- a/dom/base/nsScriptNameSpaceManager.h +++ b/dom/base/nsScriptNameSpaceManager.h @@ -240,8 +240,6 @@ private: PLDHashTable mGlobalNames; PLDHashTable mNavigatorNames; - - bool mIsInitialized; }; #endif /* nsScriptNameSpaceManager_h__ */ diff --git a/dom/xul/XULDocument.cpp b/dom/xul/XULDocument.cpp index 9c99e5b2dfc9..8d45ec1e302a 100644 --- a/dom/xul/XULDocument.cpp +++ b/dom/xul/XULDocument.cpp @@ -769,11 +769,6 @@ XULDocument::AddBroadcastListenerFor(Element& aBroadcaster, Element& aListener, if (! mBroadcasterMap) { mBroadcasterMap = PL_NewDHashTable(&gOps, sizeof(BroadcasterMapEntry)); - - if (! mBroadcasterMap) { - aRv.Throw(NS_ERROR_OUT_OF_MEMORY); - return; - } } BroadcasterMapEntry* entry = diff --git a/js/xpconnect/src/XPCJSRuntime.cpp b/js/xpconnect/src/XPCJSRuntime.cpp index 7935d12111e6..0b3df736cc08 100644 --- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -1536,9 +1536,8 @@ void XPCJSRuntime::DestroyJSContextStack() void XPCJSRuntime::SystemIsBeingShutDown() { - if (mDetachedWrappedNativeProtoMap) - mDetachedWrappedNativeProtoMap-> - Enumerate(DetachedWrappedNativeProtoShutdownMarker, nullptr); + mDetachedWrappedNativeProtoMap-> + Enumerate(DetachedWrappedNativeProtoShutdownMarker, nullptr); } #define JS_OPTIONS_DOT_STR "javascript.options." @@ -1620,51 +1619,33 @@ XPCJSRuntime::~XPCJSRuntime() JS_SetRuntimePrivate(Runtime(), nullptr); // clean up and destroy maps... - if (mWrappedJSMap) { - mWrappedJSMap->ShutdownMarker(); - delete mWrappedJSMap; - mWrappedJSMap = nullptr; - } + mWrappedJSMap->ShutdownMarker(); + delete mWrappedJSMap; + mWrappedJSMap = nullptr; - if (mWrappedJSClassMap) { - delete mWrappedJSClassMap; - mWrappedJSClassMap = nullptr; - } + delete mWrappedJSClassMap; + mWrappedJSClassMap = nullptr; - if (mIID2NativeInterfaceMap) { - delete mIID2NativeInterfaceMap; - mIID2NativeInterfaceMap = nullptr; - } + delete mIID2NativeInterfaceMap; + mIID2NativeInterfaceMap = nullptr; - if (mClassInfo2NativeSetMap) { - delete mClassInfo2NativeSetMap; - mClassInfo2NativeSetMap = nullptr; - } + delete mClassInfo2NativeSetMap; + mClassInfo2NativeSetMap = nullptr; - if (mNativeSetMap) { - delete mNativeSetMap; - mNativeSetMap = nullptr; - } + delete mNativeSetMap; + mNativeSetMap = nullptr; - if (mThisTranslatorMap) { - delete mThisTranslatorMap; - mThisTranslatorMap = nullptr; - } + delete mThisTranslatorMap; + mThisTranslatorMap = nullptr; - if (mNativeScriptableSharedMap) { - delete mNativeScriptableSharedMap; - mNativeScriptableSharedMap = nullptr; - } + delete mNativeScriptableSharedMap; + mNativeScriptableSharedMap = nullptr; - if (mDyingWrappedNativeProtoMap) { - delete mDyingWrappedNativeProtoMap; - mDyingWrappedNativeProtoMap = nullptr; - } + delete mDyingWrappedNativeProtoMap; + mDyingWrappedNativeProtoMap = nullptr; - if (mDetachedWrappedNativeProtoMap) { - delete mDetachedWrappedNativeProtoMap; - mDetachedWrappedNativeProtoMap = nullptr; - } + delete mDetachedWrappedNativeProtoMap; + mDetachedWrappedNativeProtoMap = nullptr; #ifdef MOZ_ENABLE_PROFILER_SPS // Tell the profiler that the runtime is gone @@ -3514,42 +3495,38 @@ XPCJSRuntime::DebugDump(int16_t depth) } XPC_LOG_ALWAYS(("mWrappedJSClassMap @ %x with %d wrapperclasses(s)", \ - mWrappedJSClassMap, mWrappedJSClassMap ? \ - mWrappedJSClassMap->Count() : 0)); + mWrappedJSClassMap, mWrappedJSClassMap->Count())); // iterate wrappersclasses... - if (depth && mWrappedJSClassMap && mWrappedJSClassMap->Count()) { + if (depth && mWrappedJSClassMap->Count()) { XPC_LOG_INDENT(); mWrappedJSClassMap->Enumerate(WrappedJSClassMapDumpEnumerator, &depth); XPC_LOG_OUTDENT(); } XPC_LOG_ALWAYS(("mWrappedJSMap @ %x with %d wrappers(s)", \ - mWrappedJSMap, mWrappedJSMap ? \ - mWrappedJSMap->Count() : 0)); + mWrappedJSMap, mWrappedJSMap->Count())); // iterate wrappers... - if (depth && mWrappedJSMap && mWrappedJSMap->Count()) { + if (depth && mWrappedJSMap->Count()) { XPC_LOG_INDENT(); mWrappedJSMap->Dump(depth); XPC_LOG_OUTDENT(); } XPC_LOG_ALWAYS(("mIID2NativeInterfaceMap @ %x with %d interface(s)", \ - mIID2NativeInterfaceMap, mIID2NativeInterfaceMap ? \ - mIID2NativeInterfaceMap->Count() : 0)); + mIID2NativeInterfaceMap, + mIID2NativeInterfaceMap->Count())); XPC_LOG_ALWAYS(("mClassInfo2NativeSetMap @ %x with %d sets(s)", \ - mClassInfo2NativeSetMap, mClassInfo2NativeSetMap ? \ - mClassInfo2NativeSetMap->Count() : 0)); + mClassInfo2NativeSetMap, \ + mClassInfo2NativeSetMap->Count())); XPC_LOG_ALWAYS(("mThisTranslatorMap @ %x with %d translator(s)", \ - mThisTranslatorMap, mThisTranslatorMap ? \ - mThisTranslatorMap->Count() : 0)); + mThisTranslatorMap, mThisTranslatorMap->Count())); XPC_LOG_ALWAYS(("mNativeSetMap @ %x with %d sets(s)", \ - mNativeSetMap, mNativeSetMap ? \ - mNativeSetMap->Count() : 0)); + mNativeSetMap, mNativeSetMap->Count())); // iterate sets... - if (depth && mNativeSetMap && mNativeSetMap->Count()) { + if (depth && mNativeSetMap->Count()) { XPC_LOG_INDENT(); mNativeSetMap->Enumerate(NativeSetDumpEnumerator, &depth); XPC_LOG_OUTDENT(); diff --git a/js/xpconnect/src/XPCMaps.cpp b/js/xpconnect/src/XPCMaps.cpp index c70846f570bb..d00f90443c38 100644 --- a/js/xpconnect/src/XPCMaps.cpp +++ b/js/xpconnect/src/XPCMaps.cpp @@ -169,15 +169,7 @@ JSObject2WrappedJSMap::SizeOfWrappedJS(mozilla::MallocSizeOf mallocSizeOf) const Native2WrappedNativeMap* Native2WrappedNativeMap::newMap(int length) { - Native2WrappedNativeMap* map = new Native2WrappedNativeMap(length); - if (map && map->mTable) - return map; - // Allocation of the map or the creation of its hash table has - // failed. This will cause a nullptr deref later when we attempt - // to use the map, so we abort immediately to provide a more - // useful crash stack. - NS_RUNTIMEABORT("Ran out of memory."); - return nullptr; + return new Native2WrappedNativeMap(length); } Native2WrappedNativeMap::Native2WrappedNativeMap(int length) @@ -187,8 +179,7 @@ Native2WrappedNativeMap::Native2WrappedNativeMap(int length) Native2WrappedNativeMap::~Native2WrappedNativeMap() { - if (mTable) - PL_DHashTableDestroy(mTable); + PL_DHashTableDestroy(mTable); } size_t @@ -196,7 +187,7 @@ Native2WrappedNativeMap::SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) { size_t n = 0; n += mallocSizeOf(this); - n += mTable ? PL_DHashTableSizeOfIncludingThis(mTable, SizeOfEntryExcludingThis, mallocSizeOf) : 0; + n += PL_DHashTableSizeOfIncludingThis(mTable, SizeOfEntryExcludingThis, mallocSizeOf); return n; } @@ -222,11 +213,7 @@ const struct PLDHashTableOps IID2WrappedJSClassMap::Entry::sOps = IID2WrappedJSClassMap* IID2WrappedJSClassMap::newMap(int length) { - IID2WrappedJSClassMap* map = new IID2WrappedJSClassMap(length); - if (map && map->mTable) - return map; - delete map; - return nullptr; + return new IID2WrappedJSClassMap(length); } IID2WrappedJSClassMap::IID2WrappedJSClassMap(int length) @@ -236,8 +223,7 @@ IID2WrappedJSClassMap::IID2WrappedJSClassMap(int length) IID2WrappedJSClassMap::~IID2WrappedJSClassMap() { - if (mTable) - PL_DHashTableDestroy(mTable); + PL_DHashTableDestroy(mTable); } @@ -256,11 +242,7 @@ const struct PLDHashTableOps IID2NativeInterfaceMap::Entry::sOps = IID2NativeInterfaceMap* IID2NativeInterfaceMap::newMap(int length) { - IID2NativeInterfaceMap* map = new IID2NativeInterfaceMap(length); - if (map && map->mTable) - return map; - delete map; - return nullptr; + return new IID2NativeInterfaceMap(length); } IID2NativeInterfaceMap::IID2NativeInterfaceMap(int length) @@ -270,8 +252,7 @@ IID2NativeInterfaceMap::IID2NativeInterfaceMap(int length) IID2NativeInterfaceMap::~IID2NativeInterfaceMap() { - if (mTable) - PL_DHashTableDestroy(mTable); + PL_DHashTableDestroy(mTable); } size_t @@ -279,7 +260,7 @@ IID2NativeInterfaceMap::SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) { size_t n = 0; n += mallocSizeOf(this); - n += mTable ? PL_DHashTableSizeOfIncludingThis(mTable, SizeOfEntryExcludingThis, mallocSizeOf) : 0; + n += PL_DHashTableSizeOfIncludingThis(mTable, SizeOfEntryExcludingThis, mallocSizeOf); return n; } @@ -298,11 +279,7 @@ IID2NativeInterfaceMap::SizeOfEntryExcludingThis(PLDHashEntryHdr *hdr, ClassInfo2NativeSetMap* ClassInfo2NativeSetMap::newMap(int length) { - ClassInfo2NativeSetMap* map = new ClassInfo2NativeSetMap(length); - if (map && map->mTable) - return map; - delete map; - return nullptr; + return new ClassInfo2NativeSetMap(length); } ClassInfo2NativeSetMap::ClassInfo2NativeSetMap(int length) @@ -312,8 +289,7 @@ ClassInfo2NativeSetMap::ClassInfo2NativeSetMap(int length) ClassInfo2NativeSetMap::~ClassInfo2NativeSetMap() { - if (mTable) - PL_DHashTableDestroy(mTable); + PL_DHashTableDestroy(mTable); } size_t @@ -322,7 +298,7 @@ ClassInfo2NativeSetMap::ShallowSizeOfIncludingThis(mozilla::MallocSizeOf mallocS size_t n = 0; n += mallocSizeOf(this); // The second arg is nullptr because this is a "shallow" measurement of the map. - n += mTable ? PL_DHashTableSizeOfIncludingThis(mTable, nullptr, mallocSizeOf) : 0; + n += PL_DHashTableSizeOfIncludingThis(mTable, nullptr, mallocSizeOf); return n; } @@ -333,15 +309,7 @@ ClassInfo2NativeSetMap::ShallowSizeOfIncludingThis(mozilla::MallocSizeOf mallocS ClassInfo2WrappedNativeProtoMap* ClassInfo2WrappedNativeProtoMap::newMap(int length) { - ClassInfo2WrappedNativeProtoMap* map = new ClassInfo2WrappedNativeProtoMap(length); - if (map && map->mTable) - return map; - // Allocation of the map or the creation of its hash table has - // failed. This will cause a nullptr deref later when we attempt - // to use the map, so we abort immediately to provide a more - // useful crash stack. - NS_RUNTIMEABORT("Ran out of memory."); - return nullptr; + return new ClassInfo2WrappedNativeProtoMap(length); } ClassInfo2WrappedNativeProtoMap::ClassInfo2WrappedNativeProtoMap(int length) @@ -351,8 +319,7 @@ ClassInfo2WrappedNativeProtoMap::ClassInfo2WrappedNativeProtoMap(int length) ClassInfo2WrappedNativeProtoMap::~ClassInfo2WrappedNativeProtoMap() { - if (mTable) - PL_DHashTableDestroy(mTable); + PL_DHashTableDestroy(mTable); } size_t @@ -360,7 +327,7 @@ ClassInfo2WrappedNativeProtoMap::SizeOfIncludingThis(mozilla::MallocSizeOf mallo { size_t n = 0; n += mallocSizeOf(this); - n += mTable ? PL_DHashTableSizeOfIncludingThis(mTable, SizeOfEntryExcludingThis, mallocSizeOf) : 0; + n += PL_DHashTableSizeOfIncludingThis(mTable, SizeOfEntryExcludingThis, mallocSizeOf); return n; } @@ -458,11 +425,7 @@ const struct PLDHashTableOps NativeSetMap::Entry::sOps = NativeSetMap* NativeSetMap::newMap(int length) { - NativeSetMap* map = new NativeSetMap(length); - if (map && map->mTable) - return map; - delete map; - return nullptr; + return new NativeSetMap(length); } NativeSetMap::NativeSetMap(int length) @@ -472,8 +435,7 @@ NativeSetMap::NativeSetMap(int length) NativeSetMap::~NativeSetMap() { - if (mTable) - PL_DHashTableDestroy(mTable); + PL_DHashTableDestroy(mTable); } size_t @@ -481,7 +443,7 @@ NativeSetMap::SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) { size_t n = 0; n += mallocSizeOf(this); - n += mTable ? PL_DHashTableSizeOfIncludingThis(mTable, SizeOfEntryExcludingThis, mallocSizeOf) : 0; + n += PL_DHashTableSizeOfIncludingThis(mTable, SizeOfEntryExcludingThis, mallocSizeOf); return n; } @@ -522,11 +484,7 @@ const struct PLDHashTableOps IID2ThisTranslatorMap::Entry::sOps = IID2ThisTranslatorMap* IID2ThisTranslatorMap::newMap(int length) { - IID2ThisTranslatorMap* map = new IID2ThisTranslatorMap(length); - if (map && map->mTable) - return map; - delete map; - return nullptr; + return new IID2ThisTranslatorMap(length); } IID2ThisTranslatorMap::IID2ThisTranslatorMap(int length) @@ -536,8 +494,7 @@ IID2ThisTranslatorMap::IID2ThisTranslatorMap(int length) IID2ThisTranslatorMap::~IID2ThisTranslatorMap() { - if (mTable) - PL_DHashTableDestroy(mTable); + PL_DHashTableDestroy(mTable); } /***************************************************************************/ @@ -598,12 +555,7 @@ const struct PLDHashTableOps XPCNativeScriptableSharedMap::Entry::sOps = XPCNativeScriptableSharedMap* XPCNativeScriptableSharedMap::newMap(int length) { - XPCNativeScriptableSharedMap* map = - new XPCNativeScriptableSharedMap(length); - if (map && map->mTable) - return map; - delete map; - return nullptr; + return new XPCNativeScriptableSharedMap(length); } XPCNativeScriptableSharedMap::XPCNativeScriptableSharedMap(int length) @@ -613,8 +565,7 @@ XPCNativeScriptableSharedMap::XPCNativeScriptableSharedMap(int length) XPCNativeScriptableSharedMap::~XPCNativeScriptableSharedMap() { - if (mTable) - PL_DHashTableDestroy(mTable); + PL_DHashTableDestroy(mTable); } bool @@ -650,11 +601,7 @@ XPCNativeScriptableSharedMap::GetNewOrUsed(uint32_t flags, XPCWrappedNativeProtoMap* XPCWrappedNativeProtoMap::newMap(int length) { - XPCWrappedNativeProtoMap* map = new XPCWrappedNativeProtoMap(length); - if (map && map->mTable) - return map; - delete map; - return nullptr; + return new XPCWrappedNativeProtoMap(length); } XPCWrappedNativeProtoMap::XPCWrappedNativeProtoMap(int length) @@ -665,8 +612,7 @@ XPCWrappedNativeProtoMap::XPCWrappedNativeProtoMap(int length) XPCWrappedNativeProtoMap::~XPCWrappedNativeProtoMap() { - if (mTable) - PL_DHashTableDestroy(mTable); + PL_DHashTableDestroy(mTable); } /***************************************************************************/ diff --git a/js/xpconnect/src/XPCMaps.h b/js/xpconnect/src/XPCMaps.h index ffc310112a04..413fe93065b2 100644 --- a/js/xpconnect/src/XPCMaps.h +++ b/js/xpconnect/src/XPCMaps.h @@ -32,7 +32,7 @@ class JSObject2WrappedJSMap public: static JSObject2WrappedJSMap* newMap(int length) { JSObject2WrappedJSMap* map = new JSObject2WrappedJSMap(); - if (map && map->mTable.init(length)) + if (map->mTable.init(length)) return map; delete map; return nullptr; diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 886520e04cd5..334dc8f7e2b2 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -1607,8 +1607,6 @@ nsRuleNode::ConvertChildrenToHash(int32_t aNumKids) PLDHashTable *hash = PL_NewDHashTable(&ChildrenHashOps, sizeof(ChildrenHashEntry), aNumKids); - if (!hash) - return; for (nsRuleNode* curr = ChildrenList(); curr; curr = curr->mNextSibling) { // This will never fail because of the initial size we gave the table. ChildrenHashEntry *entry = static_cast( diff --git a/modules/libpref/Preferences.cpp b/modules/libpref/Preferences.cpp index e00c1909e91a..1887ff786e91 100644 --- a/modules/libpref/Preferences.cpp +++ b/modules/libpref/Preferences.cpp @@ -523,8 +523,7 @@ Preferences::Init() { nsresult rv; - rv = PREF_Init(); - NS_ENSURE_SUCCESS(rv, rv); + PREF_Init(); rv = pref_InitInitialObjects(); NS_ENSURE_SUCCESS(rv, rv); @@ -644,8 +643,7 @@ Preferences::ResetPrefs() NotifyServiceObservers(NS_PREFSERVICE_RESET_TOPIC_ID); PREF_CleanupPrefs(); - nsresult rv = PREF_Init(); - NS_ENSURE_SUCCESS(rv, rv); + PREF_Init(); return pref_InitInitialObjects(); } diff --git a/modules/libpref/prefapi.cpp b/modules/libpref/prefapi.cpp index d0ce8bef0e52..00f3079a6bdd 100644 --- a/modules/libpref/prefapi.cpp +++ b/modules/libpref/prefapi.cpp @@ -143,19 +143,14 @@ static nsresult pref_HashPref(const char *key, PrefValue value, PrefType type, u #define PREF_HASHTABLE_INITIAL_LENGTH 1024 -nsresult PREF_Init() +void PREF_Init() { if (!gHashTable.IsInitialized()) { - if (!PL_DHashTableInit(&gHashTable, &pref_HashTableOps, - sizeof(PrefHashEntry), fallible, - PREF_HASHTABLE_INITIAL_LENGTH)) { - return NS_ERROR_OUT_OF_MEMORY; - } - + PL_DHashTableInit(&gHashTable, &pref_HashTableOps, + sizeof(PrefHashEntry), PREF_HASHTABLE_INITIAL_LENGTH); PL_INIT_ARENA_POOL(&gPrefNameArena, "PrefNameArena", PREFNAME_ARENA_SIZE); } - return NS_OK; } /* Frees the callback list. */ diff --git a/modules/libpref/prefapi.h b/modules/libpref/prefapi.h index 675b384c4751..362f8afe16a1 100644 --- a/modules/libpref/prefapi.h +++ b/modules/libpref/prefapi.h @@ -42,7 +42,7 @@ struct PrefHashEntry : PLDHashEntryHdr // the preference hashtable. // */ -nsresult PREF_Init(); +void PREF_Init(); /* // Cleanup should be called at program exit to free the diff --git a/netwerk/cache/nsCacheEntry.cpp b/netwerk/cache/nsCacheEntry.cpp index 7149bbfab687..46dcdf87034a 100644 --- a/netwerk/cache/nsCacheEntry.cpp +++ b/netwerk/cache/nsCacheEntry.cpp @@ -385,7 +385,6 @@ nsCacheEntryHashTable::ops = nsCacheEntryHashTable::nsCacheEntryHashTable() - : initialized(false) { MOZ_COUNT_CTOR(nsCacheEntryHashTable); } @@ -394,30 +393,21 @@ nsCacheEntryHashTable::nsCacheEntryHashTable() nsCacheEntryHashTable::~nsCacheEntryHashTable() { MOZ_COUNT_DTOR(nsCacheEntryHashTable); - if (initialized) - Shutdown(); + Shutdown(); } -nsresult +void nsCacheEntryHashTable::Init() { - nsresult rv = NS_OK; - initialized = PL_DHashTableInit(&table, &ops, - sizeof(nsCacheEntryHashTableEntry), - fallible, 256); - - if (!initialized) rv = NS_ERROR_OUT_OF_MEMORY; - - return rv; + PL_DHashTableInit(&table, &ops, sizeof(nsCacheEntryHashTableEntry), 256); } void nsCacheEntryHashTable::Shutdown() { - if (initialized) { + if (table.IsInitialized()) { PL_DHashTableFinish(&table); - initialized = false; } } @@ -425,8 +415,9 @@ nsCacheEntryHashTable::Shutdown() nsCacheEntry * nsCacheEntryHashTable::GetEntry( const nsCString * key) { - NS_ASSERTION(initialized, "nsCacheEntryHashTable not initialized"); - if (!initialized) return nullptr; + NS_ASSERTION(table.IsInitialized(), + "nsCacheEntryHashTable not initialized"); + if (!table.IsInitialized()) return nullptr; PLDHashEntryHdr *hashEntry = PL_DHashTableSearch(&table, key); return hashEntry ? ((nsCacheEntryHashTableEntry *)hashEntry)->cacheEntry @@ -439,8 +430,9 @@ nsCacheEntryHashTable::AddEntry( nsCacheEntry *cacheEntry) { PLDHashEntryHdr *hashEntry; - NS_ASSERTION(initialized, "nsCacheEntryHashTable not initialized"); - if (!initialized) return NS_ERROR_NOT_INITIALIZED; + NS_ASSERTION(table.IsInitialized(), + "nsCacheEntryHashTable not initialized"); + if (!table.IsInitialized()) return NS_ERROR_NOT_INITIALIZED; if (!cacheEntry) return NS_ERROR_NULL_POINTER; hashEntry = PL_DHashTableAdd(&table, &(cacheEntry->mKey)); @@ -457,10 +449,11 @@ nsCacheEntryHashTable::AddEntry( nsCacheEntry *cacheEntry) void nsCacheEntryHashTable::RemoveEntry( nsCacheEntry *cacheEntry) { - NS_ASSERTION(initialized, "nsCacheEntryHashTable not initialized"); + NS_ASSERTION(table.IsInitialized(), + "nsCacheEntryHashTable not initialized"); NS_ASSERTION(cacheEntry, "### cacheEntry == nullptr"); - if (!initialized) return; // NS_ERROR_NOT_INITIALIZED + if (!table.IsInitialized()) return; // NS_ERROR_NOT_INITIALIZED #if DEBUG // XXX debug code to make sure we have the entry we're trying to remove @@ -474,8 +467,9 @@ nsCacheEntryHashTable::RemoveEntry( nsCacheEntry *cacheEntry) void nsCacheEntryHashTable::VisitEntries( PLDHashEnumerator etor, void *arg) { - NS_ASSERTION(initialized, "nsCacheEntryHashTable not initialized"); - if (!initialized) return; // NS_ERROR_NOT_INITIALIZED + NS_ASSERTION(table.IsInitialized(), + "nsCacheEntryHashTable not initialized"); + if (!table.IsInitialized()) return; // NS_ERROR_NOT_INITIALIZED PL_DHashTableEnumerate(&table, etor, arg); } diff --git a/netwerk/cache/nsCacheEntry.h b/netwerk/cache/nsCacheEntry.h index 6772ab513b8d..5cf7ae39b52c 100644 --- a/netwerk/cache/nsCacheEntry.h +++ b/netwerk/cache/nsCacheEntry.h @@ -267,7 +267,7 @@ public: nsCacheEntryHashTable(); ~nsCacheEntryHashTable(); - nsresult Init(); + void Init(); void Shutdown(); nsCacheEntry *GetEntry( const nsCString * key); @@ -306,7 +306,6 @@ private: // member variables static const PLDHashTableOps ops; PLDHashTable table; - bool initialized; }; #endif // _nsCacheEntry_h_ diff --git a/netwerk/cache/nsCacheService.cpp b/netwerk/cache/nsCacheService.cpp index 894ad9d7c951..965e25044801 100644 --- a/netwerk/cache/nsCacheService.cpp +++ b/netwerk/cache/nsCacheService.cpp @@ -1155,8 +1155,7 @@ nsCacheService::Init() } // initialize hashtable for active cache entries - rv = mActiveEntries.Init(); - if (NS_FAILED(rv)) return rv; + mActiveEntries.Init(); // create profile/preference observer if (!mObserver) { diff --git a/netwerk/cache/nsMemoryCacheDevice.cpp b/netwerk/cache/nsMemoryCacheDevice.cpp index 8e839ff5045f..9f94dca82422 100644 --- a/netwerk/cache/nsMemoryCacheDevice.cpp +++ b/netwerk/cache/nsMemoryCacheDevice.cpp @@ -55,9 +55,9 @@ nsMemoryCacheDevice::Init() { if (mInitialized) return NS_ERROR_ALREADY_INITIALIZED; - nsresult rv = mMemCacheEntries.Init(); - mInitialized = NS_SUCCEEDED(rv); - return rv; + mMemCacheEntries.Init(); + mInitialized = true; + return NS_OK; } diff --git a/netwerk/protocol/http/nsHttp.cpp b/netwerk/protocol/http/nsHttp.cpp index 5f10195744e4..79eeb3c6ee71 100644 --- a/netwerk/protocol/http/nsHttp.cpp +++ b/netwerk/protocol/http/nsHttp.cpp @@ -105,10 +105,8 @@ nsHttp::CreateAtomTable() // The initial length for this table is a value greater than the number of // known atoms (NUM_HTTP_ATOMS) because we expect to encounter a few random // headers right off the bat. - if (!PL_DHashTableInit(&sAtomTable, &ops, sizeof(PLDHashEntryStub), - fallible, NUM_HTTP_ATOMS + 10)) { - return NS_ERROR_OUT_OF_MEMORY; - } + PL_DHashTableInit(&sAtomTable, &ops, sizeof(PLDHashEntryStub), + NUM_HTTP_ATOMS + 10); // fill the table with our known atoms const char *const atoms[] = { diff --git a/parser/htmlparser/nsHTMLEntities.cpp b/parser/htmlparser/nsHTMLEntities.cpp index ad2cdf3123b2..74bfc3eb8888 100644 --- a/parser/htmlparser/nsHTMLEntities.cpp +++ b/parser/htmlparser/nsHTMLEntities.cpp @@ -83,17 +83,10 @@ nsresult nsHTMLEntities::AddRefTable(void) { if (!gTableRefCnt) { - if (!PL_DHashTableInit(&gEntityToUnicode, &EntityToUnicodeOps, - sizeof(EntityNodeEntry), - fallible, NS_HTML_ENTITY_COUNT)) { - return NS_ERROR_OUT_OF_MEMORY; - } - if (!PL_DHashTableInit(&gUnicodeToEntity, &UnicodeToEntityOps, - sizeof(EntityNodeEntry), - fallible, NS_HTML_ENTITY_COUNT)) { - PL_DHashTableFinish(&gEntityToUnicode); - return NS_ERROR_OUT_OF_MEMORY; - } + PL_DHashTableInit(&gEntityToUnicode, &EntityToUnicodeOps, + sizeof(EntityNodeEntry), NS_HTML_ENTITY_COUNT); + PL_DHashTableInit(&gUnicodeToEntity, &UnicodeToEntityOps, + sizeof(EntityNodeEntry), NS_HTML_ENTITY_COUNT); for (const EntityNode *node = gEntityArray, *node_end = ArrayEnd(gEntityArray); node < node_end; ++node) { diff --git a/security/manager/ssl/src/nsCertTree.cpp b/security/manager/ssl/src/nsCertTree.cpp index c041079629b9..2de29024414a 100644 --- a/security/manager/ssl/src/nsCertTree.cpp +++ b/security/manager/ssl/src/nsCertTree.cpp @@ -178,14 +178,11 @@ void nsCertTree::ClearCompareHash() } } -nsresult nsCertTree::InitCompareHash() +void nsCertTree::InitCompareHash() { ClearCompareHash(); - if (!PL_DHashTableInit(&mCompareCache, &gMapOps, - sizeof(CompareCacheHashEntryPtr), fallible, 64)) { - return NS_ERROR_OUT_OF_MEMORY; - } - return NS_OK; + PL_DHashTableInit(&mCompareCache, &gMapOps, + sizeof(CompareCacheHashEntryPtr), 64); } nsCertTree::~nsCertTree() @@ -663,11 +660,11 @@ nsCertTree::LoadCertsFromCache(nsINSSCertCache *aCache, uint32_t aType) mTreeArray = nullptr; mNumRows = 0; } - nsresult rv = InitCompareHash(); - if (NS_FAILED(rv)) return rv; + InitCompareHash(); - rv = GetCertsByTypeFromCache(aCache, aType, - GetCompareFuncFromCertType(aType), &mCompareCache); + nsresult rv = + GetCertsByTypeFromCache(aCache, aType, GetCompareFuncFromCertType(aType), + &mCompareCache); if (NS_FAILED(rv)) return rv; return UpdateUIContents(); } @@ -681,11 +678,10 @@ nsCertTree::LoadCerts(uint32_t aType) mTreeArray = nullptr; mNumRows = 0; } - nsresult rv = InitCompareHash(); - if (NS_FAILED(rv)) return rv; + InitCompareHash(); - rv = GetCertsByType(aType, - GetCompareFuncFromCertType(aType), &mCompareCache); + nsresult rv = + GetCertsByType(aType, GetCompareFuncFromCertType(aType), &mCompareCache); if (NS_FAILED(rv)) return rv; return UpdateUIContents(); } diff --git a/security/manager/ssl/src/nsCertTree.h b/security/manager/ssl/src/nsCertTree.h index 877367f825e7..533ed405ab55 100644 --- a/security/manager/ssl/src/nsCertTree.h +++ b/security/manager/ssl/src/nsCertTree.h @@ -90,7 +90,7 @@ public: protected: virtual ~nsCertTree(); - nsresult InitCompareHash(); + void InitCompareHash(); void ClearCompareHash(); void RemoveCacheEntry(void *key); diff --git a/xpcom/ds/nsStaticNameTable.cpp b/xpcom/ds/nsStaticNameTable.cpp index 6d8950cf15e3..db5091e8fac6 100644 --- a/xpcom/ds/nsStaticNameTable.cpp +++ b/xpcom/ds/nsStaticNameTable.cpp @@ -138,11 +138,8 @@ nsStaticCaseInsensitiveNameTable::Init(const char* const aNames[], return false; } - if (!PL_DHashTableInit(&mNameTable, &nametable_CaseInsensitiveHashTableOps, - sizeof(NameTableEntry), fallible, - aLength)) { - return false; - } + PL_DHashTableInit(&mNameTable, &nametable_CaseInsensitiveHashTableOps, + sizeof(NameTableEntry), aLength); for (int32_t index = 0; index < aLength; ++index) { const char* raw = aNames[index]; diff --git a/xpcom/glue/pldhash.cpp b/xpcom/glue/pldhash.cpp index b6f93fd3b3ea..5c547d08285b 100644 --- a/xpcom/glue/pldhash.cpp +++ b/xpcom/glue/pldhash.cpp @@ -171,15 +171,8 @@ PLDHashTable* PL_NewDHashTable(const PLDHashTableOps* aOps, uint32_t aEntrySize, uint32_t aLength) { - PLDHashTable* table = (PLDHashTable*)malloc(sizeof(*table)); - - if (!table) { - return nullptr; - } - if (!PL_DHashTableInit(table, aOps, aEntrySize, fallible, aLength)) { - free(table); - return nullptr; - } + PLDHashTable* table = new PLDHashTable(); + PL_DHashTableInit(table, aOps, aEntrySize, aLength); return table; } @@ -187,7 +180,7 @@ void PL_DHashTableDestroy(PLDHashTable* aTable) { PL_DHashTableFinish(aTable); - free(aTable); + delete aTable; } /* @@ -219,12 +212,12 @@ MinCapacity(uint32_t aLength) return (aLength * 4 + (3 - 1)) / 3; // == ceil(aLength * 4 / 3) } -MOZ_ALWAYS_INLINE bool +MOZ_ALWAYS_INLINE void PLDHashTable::Init(const PLDHashTableOps* aOps, - uint32_t aEntrySize, const fallible_t&, uint32_t aLength) + uint32_t aEntrySize, uint32_t aLength) { if (aLength > PL_DHASH_MAX_INITIAL_LENGTH) { - return false; + MOZ_CRASH("Initial length is too large"); } // Compute the smallest capacity allowing |aLength| elements to be inserted @@ -238,51 +231,30 @@ PLDHashTable::Init(const PLDHashTableOps* aOps, capacity = 1u << log2; MOZ_ASSERT(capacity <= PL_DHASH_MAX_CAPACITY); + mOps = aOps; mHashShift = PL_DHASH_BITS - log2; mEntrySize = aEntrySize; mEntryCount = mRemovedCount = 0; mGeneration = 0; uint32_t nbytes; if (!SizeOfEntryStore(capacity, aEntrySize, &nbytes)) { - return false; // overflowed + MOZ_CRASH("Initial entry store size is too large"); } mEntryStore = nullptr; METER(memset(&mStats, 0, sizeof(mStats))); - // Set this only once we reach a point where we know we can't fail. - mOps = aOps; - #ifdef DEBUG mRecursionLevel = 0; #endif - - return true; -} - -bool -PL_DHashTableInit(PLDHashTable* aTable, const PLDHashTableOps* aOps, - uint32_t aEntrySize, - const fallible_t& aFallible, uint32_t aLength) -{ - return aTable->Init(aOps, aEntrySize, aFallible, aLength); } void PL_DHashTableInit(PLDHashTable* aTable, const PLDHashTableOps* aOps, uint32_t aEntrySize, uint32_t aLength) { - if (!PL_DHashTableInit(aTable, aOps, aEntrySize, fallible, aLength)) { - if (aLength > PL_DHASH_MAX_INITIAL_LENGTH) { - MOZ_CRASH(); // the asked-for length was too big - } - uint32_t capacity = MinCapacity(aLength), nbytes; - if (!SizeOfEntryStore(capacity, aEntrySize, &nbytes)) { - MOZ_CRASH(); // the required mEntryStore size was too big - } - NS_ABORT_OOM(nbytes); // allocation failed - } + aTable->Init(aOps, aEntrySize, aLength); } /* diff --git a/xpcom/glue/pldhash.h b/xpcom/glue/pldhash.h index 0660ee103e5a..f4285fc2d6d7 100644 --- a/xpcom/glue/pldhash.h +++ b/xpcom/glue/pldhash.h @@ -10,7 +10,6 @@ * Double hashing, a la Knuth 6. */ #include "mozilla/Attributes.h" // for MOZ_ALWAYS_INLINE -#include "mozilla/fallible.h" #include "mozilla/MemoryReporting.h" #include "mozilla/Types.h" #include "nscore.h" @@ -240,8 +239,7 @@ public: uint32_t EntryCount() const { return mEntryCount; } uint32_t Generation() const { return mGeneration; } - bool Init(const PLDHashTableOps* aOps, uint32_t aEntrySize, - const mozilla::fallible_t&, uint32_t aLength); + void Init(const PLDHashTableOps* aOps, uint32_t aEntrySize, uint32_t aLength); void Finish(); @@ -436,7 +434,7 @@ const PLDHashTableOps* PL_DHashGetStubOps(void); /* * Dynamically allocate a new PLDHashTable, initialize it using - * PL_DHashTableInit, and return its address. Return null on allocation failure. + * PL_DHashTableInit, and return its address. Never returns null. */ PLDHashTable* PL_NewDHashTable( const PLDHashTableOps* aOps, uint32_t aEntrySize, @@ -463,15 +461,6 @@ void PL_DHashTableInit( PLDHashTable* aTable, const PLDHashTableOps* aOps, uint32_t aEntrySize, uint32_t aLength = PL_DHASH_DEFAULT_INITIAL_LENGTH); -/* - * Initialize aTable. This is the same as PL_DHashTableInit, except that it - * returns a boolean indicating success, rather than crashing on failure. - */ -MOZ_WARN_UNUSED_RESULT bool PL_DHashTableInit( - PLDHashTable* aTable, const PLDHashTableOps* aOps, - uint32_t aEntrySize, const mozilla::fallible_t&, - uint32_t aLength = PL_DHASH_DEFAULT_INITIAL_LENGTH); - /* * Free |aTable|'s entry storage (via aTable->mOps->freeTable). Use this * function to destroy a PLDHashTable that is allocated on the stack or in diff --git a/xpcom/tests/TestPLDHash.cpp b/xpcom/tests/TestPLDHash.cpp index 9d14d16791e4..b9299e79ceaa 100644 --- a/xpcom/tests/TestPLDHash.cpp +++ b/xpcom/tests/TestPLDHash.cpp @@ -22,12 +22,20 @@ static bool test_pldhash_Init_capacity_ok() } // Try the largest allowed capacity. With PL_DHASH_MAX_CAPACITY==1<<26, this - // will allocate 0.5GB of entry store on 32-bit platforms and 1GB on 64-bit - // platforms. - if (!PL_DHashTableInit(&t, PL_DHashGetStubOps(), sizeof(PLDHashEntryStub), - mozilla::fallible, PL_DHASH_MAX_INITIAL_LENGTH)) { - return false; - } + // would allocate (if we added an element) 0.5GB of entry store on 32-bit + // platforms and 1GB on 64-bit platforms. + // + // Ideally we'd also try (a) a too-large capacity, and (b) a large capacity + // combined with a large entry size that when multipled overflow. But those + // cases would cause the test to abort immediately. + // + // Furthermore, ideally we'd also try a large-but-ok capacity that almost but + // doesn't quite overflow, but that would result in allocating just under 4GB + // of entry storage. That's very likely to fail on 32-bit platforms, so such + // a test wouldn't be reliable. + // + PL_DHashTableInit(&t, PL_DHashGetStubOps(), sizeof(PLDHashEntryStub), + PL_DHASH_MAX_INITIAL_LENGTH); // Check that Init() sets |ops|. if (!t.IsInitialized()) { @@ -43,67 +51,6 @@ static bool test_pldhash_Init_capacity_ok() return true; } -static bool test_pldhash_Init_capacity_too_large() -{ - PLDHashTable t; - - // Check that the constructor nulls |ops|. - if (t.IsInitialized()) { - return false; - } - - // Try the smallest too-large capacity. - if (PL_DHashTableInit(&t, PL_DHashGetStubOps(), - sizeof(PLDHashEntryStub), - mozilla::fallible, - PL_DHASH_MAX_INITIAL_LENGTH + 1)) { - return false; // it succeeded!? - } - // Don't call PL_DHashTableFinish() here; it's not safe after Init() failure. - - // Check that |ops| is still null. - if (t.IsInitialized()) { - return false; - } - - return true; -} - -static bool test_pldhash_Init_overflow() -{ - PLDHashTable t; - - // Check that the constructor nulls |ops|. - if (t.IsInitialized()) { - return false; - } - - // Try an acceptable capacity, but one whose byte size overflows uint32_t. - // - // Ideally we'd also try a large-but-ok capacity that almost but doesn't - // quite overflow, but that would result in allocating just under 4GB of - // entry storage. That's very likely to fail on 32-bit platforms, so such a - // test wouldn't be reliable. - - struct OneKBEntry { - PLDHashEntryHdr hdr; - char buf[1024 - sizeof(PLDHashEntryHdr)]; - }; - - if (PL_DHashTableInit(&t, PL_DHashGetStubOps(), sizeof(OneKBEntry), - mozilla::fallible, PL_DHASH_MAX_INITIAL_LENGTH)) { - return false; // it succeeded!? - } - // Don't call PL_DHashTableFinish() here; it's not safe after Init() failure. - - // Check that |ops| is still null. - if (t.IsInitialized()) { - return false; - } - - return true; -} - static bool test_pldhash_lazy_storage() { PLDHashTable t; @@ -225,8 +172,6 @@ static const struct Test { TestFunc func; } tests[] = { DECL_TEST(test_pldhash_Init_capacity_ok), - DECL_TEST(test_pldhash_Init_capacity_too_large), - DECL_TEST(test_pldhash_Init_overflow), DECL_TEST(test_pldhash_lazy_storage), // See bug 931062, we skip this test on Android due to OOM. #ifndef MOZ_WIDGET_ANDROID From f325953043e8a08dbe5ed2565b1f1f5f7ae2a6d2 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sun, 1 Feb 2015 20:36:52 -0800 Subject: [PATCH 37/74] Bug 1050035 (part 3) - Remove PL_NewDHashTable() and PL_DHashTableDestroy(). r=froydnj. Because they are now just equivalent to |new PLDHashTable()| + PL_DHashTableInit() and PL_DHashTableFinish(t) + |delete t|, respectively. They're only used in a handful of places and obscure things more than they clarify -- I only recently worked out exactly how they different from Init() and Finish(). --HG-- extra : rebase_source : c958491447523becff3e01de45a5d2d227d1ecd3 --- dom/base/nsDocument.cpp | 14 ++++---- dom/xul/XULDocument.cpp | 6 ++-- js/xpconnect/src/XPCMaps.cpp | 56 ++++++++++++++++++++----------- layout/style/nsRuleNode.cpp | 12 ++++--- rdf/base/nsInMemoryDataSource.cpp | 8 +++-- xpcom/glue/pldhash.cpp | 16 --------- xpcom/glue/pldhash.h | 20 ++--------- xpcom/tests/TestPLDHash.cpp | 13 +++---- 8 files changed, 67 insertions(+), 78 deletions(-) diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 213697bd58da..7e159ebf9a36 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -1715,8 +1715,8 @@ nsDocument::~nsDocument() // Kill the subdocument map, doing this will release its strong // references, if any. if (mSubDocuments) { - PL_DHashTableDestroy(mSubDocuments); - + PL_DHashTableFinish(mSubDocuments); + delete mSubDocuments; mSubDocuments = nullptr; } @@ -2126,7 +2126,8 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument) } if (tmp->mSubDocuments) { - PL_DHashTableDestroy(tmp->mSubDocuments); + PL_DHashTableFinish(tmp->mSubDocuments); + delete tmp->mSubDocuments; tmp->mSubDocuments = nullptr; } @@ -2331,8 +2332,8 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup, // Delete references to sub-documents and kill the subdocument map, // if any. It holds strong references if (mSubDocuments) { - PL_DHashTableDestroy(mSubDocuments); - + PL_DHashTableFinish(mSubDocuments); + delete mSubDocuments; mSubDocuments = nullptr; } @@ -3984,7 +3985,8 @@ nsDocument::SetSubDocumentFor(Element* aElement, nsIDocument* aSubDoc) SubDocInitEntry }; - mSubDocuments = PL_NewDHashTable(&hash_table_ops, sizeof(SubDocMapEntry)); + mSubDocuments = new PLDHashTable(); + PL_DHashTableInit(mSubDocuments, &hash_table_ops, sizeof(SubDocMapEntry)); } // Add a mapping to the hash table diff --git a/dom/xul/XULDocument.cpp b/dom/xul/XULDocument.cpp index 8d45ec1e302a..ac978f45cd17 100644 --- a/dom/xul/XULDocument.cpp +++ b/dom/xul/XULDocument.cpp @@ -216,7 +216,8 @@ XULDocument::~XULDocument() // Destroy our broadcaster map. if (mBroadcasterMap) { - PL_DHashTableDestroy(mBroadcasterMap); + PL_DHashTableFinish(mBroadcasterMap); + delete mBroadcasterMap; } delete mTemplateBuilderTable; @@ -768,7 +769,8 @@ XULDocument::AddBroadcastListenerFor(Element& aBroadcaster, Element& aListener, }; if (! mBroadcasterMap) { - mBroadcasterMap = PL_NewDHashTable(&gOps, sizeof(BroadcasterMapEntry)); + mBroadcasterMap = new PLDHashTable(); + PL_DHashTableInit(mBroadcasterMap, &gOps, sizeof(BroadcasterMapEntry)); } BroadcasterMapEntry* entry = diff --git a/js/xpconnect/src/XPCMaps.cpp b/js/xpconnect/src/XPCMaps.cpp index d00f90443c38..d5c5b4f81e23 100644 --- a/js/xpconnect/src/XPCMaps.cpp +++ b/js/xpconnect/src/XPCMaps.cpp @@ -174,12 +174,14 @@ Native2WrappedNativeMap::newMap(int length) Native2WrappedNativeMap::Native2WrappedNativeMap(int length) { - mTable = PL_NewDHashTable(PL_DHashGetStubOps(), sizeof(Entry), length); + mTable = new PLDHashTable(); + PL_DHashTableInit(mTable, PL_DHashGetStubOps(), sizeof(Entry), length); } Native2WrappedNativeMap::~Native2WrappedNativeMap() { - PL_DHashTableDestroy(mTable); + PL_DHashTableFinish(mTable); + delete mTable; } size_t @@ -218,12 +220,14 @@ IID2WrappedJSClassMap::newMap(int length) IID2WrappedJSClassMap::IID2WrappedJSClassMap(int length) { - mTable = PL_NewDHashTable(&Entry::sOps, sizeof(Entry), length); + mTable = new PLDHashTable(); + PL_DHashTableInit(mTable, &Entry::sOps, sizeof(Entry), length); } IID2WrappedJSClassMap::~IID2WrappedJSClassMap() { - PL_DHashTableDestroy(mTable); + PL_DHashTableFinish(mTable); + delete mTable; } @@ -247,12 +251,14 @@ IID2NativeInterfaceMap::newMap(int length) IID2NativeInterfaceMap::IID2NativeInterfaceMap(int length) { - mTable = PL_NewDHashTable(&Entry::sOps, sizeof(Entry), length); + mTable = new PLDHashTable(); + PL_DHashTableInit(mTable, &Entry::sOps, sizeof(Entry), length); } IID2NativeInterfaceMap::~IID2NativeInterfaceMap() { - PL_DHashTableDestroy(mTable); + PL_DHashTableFinish(mTable); + delete mTable; } size_t @@ -284,12 +290,14 @@ ClassInfo2NativeSetMap::newMap(int length) ClassInfo2NativeSetMap::ClassInfo2NativeSetMap(int length) { - mTable = PL_NewDHashTable(PL_DHashGetStubOps(), sizeof(Entry), length); + mTable = new PLDHashTable(); + PL_DHashTableInit(mTable, PL_DHashGetStubOps(), sizeof(Entry), length); } ClassInfo2NativeSetMap::~ClassInfo2NativeSetMap() { - PL_DHashTableDestroy(mTable); + PL_DHashTableFinish(mTable); + delete mTable; } size_t @@ -314,12 +322,14 @@ ClassInfo2WrappedNativeProtoMap::newMap(int length) ClassInfo2WrappedNativeProtoMap::ClassInfo2WrappedNativeProtoMap(int length) { - mTable = PL_NewDHashTable(PL_DHashGetStubOps(), sizeof(Entry), length); + mTable = new PLDHashTable(); + PL_DHashTableInit(mTable, PL_DHashGetStubOps(), sizeof(Entry), length); } ClassInfo2WrappedNativeProtoMap::~ClassInfo2WrappedNativeProtoMap() { - PL_DHashTableDestroy(mTable); + PL_DHashTableFinish(mTable); + delete mTable; } size_t @@ -430,12 +440,14 @@ NativeSetMap::newMap(int length) NativeSetMap::NativeSetMap(int length) { - mTable = PL_NewDHashTable(&Entry::sOps, sizeof(Entry), length); + mTable = new PLDHashTable(); + PL_DHashTableInit(mTable, &Entry::sOps, sizeof(Entry), length); } NativeSetMap::~NativeSetMap() { - PL_DHashTableDestroy(mTable); + PL_DHashTableFinish(mTable); + delete mTable; } size_t @@ -489,12 +501,14 @@ IID2ThisTranslatorMap::newMap(int length) IID2ThisTranslatorMap::IID2ThisTranslatorMap(int length) { - mTable = PL_NewDHashTable(&Entry::sOps, sizeof(Entry), length); + mTable = new PLDHashTable(); + PL_DHashTableInit(mTable, &Entry::sOps, sizeof(Entry), length); } IID2ThisTranslatorMap::~IID2ThisTranslatorMap() { - PL_DHashTableDestroy(mTable); + PL_DHashTableFinish(mTable); + delete mTable; } /***************************************************************************/ @@ -560,12 +574,14 @@ XPCNativeScriptableSharedMap::newMap(int length) XPCNativeScriptableSharedMap::XPCNativeScriptableSharedMap(int length) { - mTable = PL_NewDHashTable(&Entry::sOps, sizeof(Entry), length); + mTable = new PLDHashTable(); + PL_DHashTableInit(mTable, &Entry::sOps, sizeof(Entry), length); } XPCNativeScriptableSharedMap::~XPCNativeScriptableSharedMap() { - PL_DHashTableDestroy(mTable); + PL_DHashTableFinish(mTable); + delete mTable; } bool @@ -606,13 +622,15 @@ XPCWrappedNativeProtoMap::newMap(int length) XPCWrappedNativeProtoMap::XPCWrappedNativeProtoMap(int length) { - mTable = PL_NewDHashTable(PL_DHashGetStubOps(), - sizeof(PLDHashEntryStub), length); + mTable = new PLDHashTable(); + PL_DHashTableInit(mTable, PL_DHashGetStubOps(), sizeof(PLDHashEntryStub), + length); } XPCWrappedNativeProtoMap::~XPCWrappedNativeProtoMap() { - PL_DHashTableDestroy(mTable); + PL_DHashTableFinish(mTable); + delete mTable; } /***************************************************************************/ diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 334dc8f7e2b2..f7831ee60255 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -1421,7 +1421,8 @@ nsRuleNode::DestroyInternal(nsRuleNode ***aDestroyQueueTail) PL_DHashTableEnumerate(children, EnqueueRuleNodeChildren, &destroyQueueTail); *destroyQueueTail = nullptr; // ensure null-termination - PL_DHashTableDestroy(children); + PL_DHashTableFinish(children); + delete children; } else if (HaveChildren()) { *destroyQueueTail = ChildrenList(); do { @@ -1604,9 +1605,9 @@ nsRuleNode::ConvertChildrenToHash(int32_t aNumKids) { NS_ASSERTION(!ChildrenAreHashed() && HaveChildren(), "must have a non-empty list of children"); - PLDHashTable *hash = PL_NewDHashTable(&ChildrenHashOps, - sizeof(ChildrenHashEntry), - aNumKids); + PLDHashTable *hash = new PLDHashTable(); + PL_DHashTableInit(hash, &ChildrenHashOps, sizeof(ChildrenHashEntry), + aNumKids); for (nsRuleNode* curr = ChildrenList(); curr; curr = curr->mNextSibling) { // This will never fail because of the initial size we gave the table. ChildrenHashEntry *entry = static_cast( @@ -9231,7 +9232,8 @@ nsRuleNode::SweepChildren(nsTArray& aSweepQueue) PL_DHashTableEnumerate(children, SweepHashEntry, &survivorsWithChildren); childrenDestroyed = oldChildCount - children->EntryCount(); if (childrenDestroyed == oldChildCount) { - PL_DHashTableDestroy(children); + PL_DHashTableFinish(children); + delete children; mChildren.asVoid = nullptr; } } else { diff --git a/rdf/base/nsInMemoryDataSource.cpp b/rdf/base/nsInMemoryDataSource.cpp index 61de79fe6fc0..61a3fc07880f 100644 --- a/rdf/base/nsInMemoryDataSource.cpp +++ b/rdf/base/nsInMemoryDataSource.cpp @@ -162,8 +162,9 @@ Assertion::Assertion(nsIRDFResource* aSource) NS_ADDREF(mSource); - u.hash.mPropertyHash = - PL_NewDHashTable(PL_DHashGetStubOps(), sizeof(Entry)); + u.hash.mPropertyHash = new PLDHashTable(); + PL_DHashTableInit(u.hash.mPropertyHash, PL_DHashGetStubOps(), + sizeof(Entry)); } Assertion::Assertion(nsIRDFResource* aSource, @@ -194,7 +195,8 @@ Assertion::~Assertion() if (mHashEntry && u.hash.mPropertyHash) { PL_DHashTableEnumerate(u.hash.mPropertyHash, DeletePropertyHashEntry, nullptr); - PL_DHashTableDestroy(u.hash.mPropertyHash); + PL_DHashTableFinish(u.hash.mPropertyHash); + delete u.hash.mPropertyHash; u.hash.mPropertyHash = nullptr; } diff --git a/xpcom/glue/pldhash.cpp b/xpcom/glue/pldhash.cpp index 5c547d08285b..d284d1ec2428 100644 --- a/xpcom/glue/pldhash.cpp +++ b/xpcom/glue/pldhash.cpp @@ -167,22 +167,6 @@ SizeOfEntryStore(uint32_t aCapacity, uint32_t aEntrySize, uint32_t* aNbytes) return uint64_t(*aNbytes) == nbytes64; // returns false on overflow } -PLDHashTable* -PL_NewDHashTable(const PLDHashTableOps* aOps, uint32_t aEntrySize, - uint32_t aLength) -{ - PLDHashTable* table = new PLDHashTable(); - PL_DHashTableInit(table, aOps, aEntrySize, aLength); - return table; -} - -void -PL_DHashTableDestroy(PLDHashTable* aTable) -{ - PL_DHashTableFinish(aTable); - delete aTable; -} - /* * Compute max and min load numbers (entry counts). We have a secondary max * that allows us to overload a table reasonably if it cannot be grown further diff --git a/xpcom/glue/pldhash.h b/xpcom/glue/pldhash.h index f4285fc2d6d7..e820aa067a9d 100644 --- a/xpcom/glue/pldhash.h +++ b/xpcom/glue/pldhash.h @@ -432,21 +432,6 @@ void PL_DHashFreeStringKey(PLDHashTable* aTable, PLDHashEntryHdr* aEntry); */ const PLDHashTableOps* PL_DHashGetStubOps(void); -/* - * Dynamically allocate a new PLDHashTable, initialize it using - * PL_DHashTableInit, and return its address. Never returns null. - */ -PLDHashTable* PL_NewDHashTable( - const PLDHashTableOps* aOps, uint32_t aEntrySize, - uint32_t aLength = PL_DHASH_DEFAULT_INITIAL_LENGTH); - -/* - * Free |aTable|'s entry storage and |aTable| itself (both via - * aTable->mOps->freeTable). Use this function to destroy a PLDHashTable that - * was allocated on the heap via PL_NewDHashTable(). - */ -void PL_DHashTableDestroy(PLDHashTable* aTable); - /* * Initialize aTable with aOps and aEntrySize. The table's initial capacity * will be chosen such that |aLength| elements can be inserted without @@ -462,9 +447,8 @@ void PL_DHashTableInit( uint32_t aEntrySize, uint32_t aLength = PL_DHASH_DEFAULT_INITIAL_LENGTH); /* - * Free |aTable|'s entry storage (via aTable->mOps->freeTable). Use this - * function to destroy a PLDHashTable that is allocated on the stack or in - * static memory and was created via PL_DHashTableInit(). + * Clear |aTable|'s elements (via aTable->mOps->clearEntry) and free its entry + * storage, if has any. */ void PL_DHashTableFinish(PLDHashTable* aTable); diff --git a/xpcom/tests/TestPLDHash.cpp b/xpcom/tests/TestPLDHash.cpp index b9299e79ceaa..3b56e367b62e 100644 --- a/xpcom/tests/TestPLDHash.cpp +++ b/xpcom/tests/TestPLDHash.cpp @@ -133,18 +133,13 @@ static bool test_pldhash_grow_to_max_capacity() nullptr }; - // This is infallible. - PLDHashTable* t = PL_NewDHashTable(&ops, sizeof(PLDHashEntryStub), 128); - - // Check that New() sets |t->ops|. - if (!t->IsInitialized()) { - return false; - } + PLDHashTable t; + PL_DHashTableInit(&t, &ops, sizeof(PLDHashEntryStub), 128); // Keep inserting elements until failure occurs because the table is full. size_t numInserted = 0; while (true) { - if (!PL_DHashTableAdd(t, (const void*)numInserted)) { + if (!PL_DHashTableAdd(&t, (const void*)numInserted)) { break; } numInserted++; @@ -156,7 +151,7 @@ static bool test_pldhash_grow_to_max_capacity() return false; } - PL_DHashTableDestroy(t); + PL_DHashTableFinish(&t); return true; } From b5913e0b3dee59c3dd11182a8a218fdefd9b17d1 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 2 Feb 2015 14:48:58 -0800 Subject: [PATCH 38/74] Bug 1050035 (part 4) - Make PL_DHashTableAdd() infallible by default, and add a fallible alternative. r=froydnj. I kept all the existing PL_DHashTableAdd() calls fallible, in order to be conservative, except for the ones in nsAtomTable.cpp which already were followed immediately by an abort on failure. --HG-- extra : rebase_source : eeba14d732077ef2e412f4caca852de6b6b85f55 --- dom/base/nsContentList.cpp | 5 ++-- dom/base/nsContentUtils.cpp | 2 +- dom/base/nsDocument.cpp | 5 ++-- dom/base/nsPropertyTable.cpp | 2 +- dom/base/nsScriptNameSpaceManager.cpp | 5 ++-- dom/plugins/base/nsJSNPRuntime.cpp | 4 +-- dom/xul/XULDocument.cpp | 5 ++-- dom/xul/templates/nsContentSupportMap.h | 3 ++- dom/xul/templates/nsTemplateMap.h | 3 ++- .../commandhandler/nsCommandParams.cpp | 3 ++- gfx/thebes/gfxFT2FontList.cpp | 10 +++---- js/xpconnect/src/XPCMaps.cpp | 3 ++- js/xpconnect/src/XPCMaps.h | 26 ++++++++++++------- layout/base/nsFrameManager.cpp | 5 ++-- layout/style/nsCSSRuleProcessor.cpp | 20 +++++++------- layout/style/nsHTMLStyleSheet.cpp | 7 ++--- layout/style/nsRuleNode.cpp | 4 +-- layout/tables/SpanningCellSorter.cpp | 3 ++- modules/libpref/prefapi.cpp | 3 ++- netwerk/base/nsLoadGroup.cpp | 5 ++-- netwerk/cache/nsCacheEntry.cpp | 2 +- netwerk/cache/nsDiskCacheBinding.cpp | 3 ++- netwerk/dns/nsHostResolver.cpp | 2 +- netwerk/protocol/http/nsHttp.cpp | 4 +-- parser/htmlparser/nsHTMLEntities.cpp | 5 ++-- rdf/base/nsInMemoryDataSource.cpp | 17 +++++++----- rdf/base/nsRDFService.cpp | 10 +++---- .../boot/src/nsSecureBrowserUIImpl.cpp | 4 +-- security/manager/ssl/src/nsCertTree.cpp | 5 ++-- security/manager/ssl/src/nsNSSShutDown.cpp | 4 +-- uriloader/base/nsDocLoader.cpp | 2 +- xpcom/base/nsCycleCollector.cpp | 4 +-- xpcom/ds/nsAtomTable.cpp | 16 +++--------- xpcom/ds/nsPersistentProperties.cpp | 2 +- xpcom/ds/nsStaticNameTable.cpp | 4 +-- xpcom/glue/nsTHashtable.h | 22 +++++++++------- xpcom/glue/pldhash.cpp | 18 +++++++++++-- xpcom/glue/pldhash.h | 13 ++++++++-- xpcom/tests/TestPLDHash.cpp | 2 +- 39 files changed, 146 insertions(+), 116 deletions(-) diff --git a/dom/base/nsContentList.cpp b/dom/base/nsContentList.cpp index 9d9dc76509bc..7a4a0f2d3ea0 100644 --- a/dom/base/nsContentList.cpp +++ b/dom/base/nsContentList.cpp @@ -224,7 +224,7 @@ NS_GetContentList(nsINode* aRootNode, // First we look in our hashtable. Then we create a content list if needed if (gContentListHashTable.IsInitialized()) { entry = static_cast - (PL_DHashTableAdd(&gContentListHashTable, &hashKey)); + (PL_DHashTableAdd(&gContentListHashTable, &hashKey, fallible)); if (entry) list = entry->mContentList; } @@ -332,8 +332,7 @@ GetFuncStringContentList(nsINode* aRootNode, nsFuncStringCacheKey hashKey(aRootNode, aFunc, aString); entry = static_cast - (PL_DHashTableAdd(&gFuncStringContentListHashTable, - &hashKey)); + (PL_DHashTableAdd(&gFuncStringContentListHashTable, &hashKey, fallible)); if (entry) { list = entry->mContentList; #ifdef DEBUG diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 63dacabbb110..311205c8f5ea 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -3960,7 +3960,7 @@ nsContentUtils::GetListenerManagerForNode(nsINode *aNode) EventListenerManagerMapEntry *entry = static_cast - (PL_DHashTableAdd(&sEventListenerManagersHash, aNode)); + (PL_DHashTableAdd(&sEventListenerManagersHash, aNode, fallible)); if (!entry) { return nullptr; diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 7e159ebf9a36..b45292183c70 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -3990,9 +3990,8 @@ nsDocument::SetSubDocumentFor(Element* aElement, nsIDocument* aSubDoc) } // Add a mapping to the hash table - SubDocMapEntry *entry = - static_cast - (PL_DHashTableAdd(mSubDocuments, aElement)); + SubDocMapEntry *entry = static_cast + (PL_DHashTableAdd(mSubDocuments, aElement, fallible)); if (!entry) { return NS_ERROR_OUT_OF_MEMORY; diff --git a/dom/base/nsPropertyTable.cpp b/dom/base/nsPropertyTable.cpp index 0dec88123e81..13e42240b462 100644 --- a/dom/base/nsPropertyTable.cpp +++ b/dom/base/nsPropertyTable.cpp @@ -230,7 +230,7 @@ nsPropertyTable::SetPropertyInternal(nsPropertyOwner aObject, // value is destroyed nsresult result = NS_OK; PropertyListMapEntry *entry = static_cast - (PL_DHashTableAdd(&propertyList->mObjectValueMap, aObject)); + (PL_DHashTableAdd(&propertyList->mObjectValueMap, aObject, fallible)); if (!entry) return NS_ERROR_OUT_OF_MEMORY; // A nullptr entry->key is the sign that the entry has just been allocated diff --git a/dom/base/nsScriptNameSpaceManager.cpp b/dom/base/nsScriptNameSpaceManager.cpp index eab3042bfbc8..e0d12f9b4c7b 100644 --- a/dom/base/nsScriptNameSpaceManager.cpp +++ b/dom/base/nsScriptNameSpaceManager.cpp @@ -139,9 +139,8 @@ nsGlobalNameStruct * nsScriptNameSpaceManager::AddToHash(PLDHashTable *aTable, const nsAString *aKey, const char16_t **aClassName) { - GlobalNameMapEntry *entry = - static_cast - (PL_DHashTableAdd(aTable, aKey)); + GlobalNameMapEntry *entry = static_cast + (PL_DHashTableAdd(aTable, aKey, fallible)); if (!entry) { return nullptr; diff --git a/dom/plugins/base/nsJSNPRuntime.cpp b/dom/plugins/base/nsJSNPRuntime.cpp index 562fde7fec76..874fe228ddce 100644 --- a/dom/plugins/base/nsJSNPRuntime.cpp +++ b/dom/plugins/base/nsJSNPRuntime.cpp @@ -1872,7 +1872,7 @@ nsNPObjWrapper::GetNewOrUsed(NPP npp, JSContext *cx, NPObject *npobj) } NPObjWrapperHashEntry *entry = static_cast - (PL_DHashTableAdd(&sNPObjWrappers, npobj)); + (PL_DHashTableAdd(&sNPObjWrappers, npobj, fallible)); if (!entry) { // Out of memory @@ -2035,7 +2035,7 @@ LookupNPP(NPObject *npobj) } NPObjWrapperHashEntry *entry = static_cast - (PL_DHashTableAdd(&sNPObjWrappers, npobj)); + (PL_DHashTableAdd(&sNPObjWrappers, npobj, fallible)); if (!entry) { return nullptr; diff --git a/dom/xul/XULDocument.cpp b/dom/xul/XULDocument.cpp index ac978f45cd17..ee8d956cf890 100644 --- a/dom/xul/XULDocument.cpp +++ b/dom/xul/XULDocument.cpp @@ -778,9 +778,8 @@ XULDocument::AddBroadcastListenerFor(Element& aBroadcaster, Element& aListener, (PL_DHashTableSearch(mBroadcasterMap, &aBroadcaster)); if (!entry) { - entry = - static_cast - (PL_DHashTableAdd(mBroadcasterMap, &aBroadcaster)); + entry = static_cast + (PL_DHashTableAdd(mBroadcasterMap, &aBroadcaster, fallible)); if (! entry) { aRv.Throw(NS_ERROR_OUT_OF_MEMORY); diff --git a/dom/xul/templates/nsContentSupportMap.h b/dom/xul/templates/nsContentSupportMap.h index 253dbbe989b5..f61a09027a7e 100644 --- a/dom/xul/templates/nsContentSupportMap.h +++ b/dom/xul/templates/nsContentSupportMap.h @@ -28,7 +28,8 @@ public: if (!mMap.IsInitialized()) return NS_ERROR_NOT_INITIALIZED; - PLDHashEntryHdr* hdr = PL_DHashTableAdd(&mMap, aElement); + PLDHashEntryHdr* hdr = + PL_DHashTableAdd(&mMap, aElement, mozilla::fallible); if (!hdr) return NS_ERROR_OUT_OF_MEMORY; diff --git a/dom/xul/templates/nsTemplateMap.h b/dom/xul/templates/nsTemplateMap.h index e87faa41086c..71203f559746 100644 --- a/dom/xul/templates/nsTemplateMap.h +++ b/dom/xul/templates/nsTemplateMap.h @@ -37,7 +37,8 @@ public: NS_ASSERTION(!PL_DHashTableSearch(&mTable, aContent), "aContent already in map"); - Entry* entry = static_cast(PL_DHashTableAdd(&mTable, aContent)); + Entry* entry = static_cast + (PL_DHashTableAdd(&mTable, aContent, fallible)); if (entry) { entry->mContent = aContent; diff --git a/embedding/components/commandhandler/nsCommandParams.cpp b/embedding/components/commandhandler/nsCommandParams.cpp index 2bfc80e670c0..cc36ee2c8f0e 100644 --- a/embedding/components/commandhandler/nsCommandParams.cpp +++ b/embedding/components/commandhandler/nsCommandParams.cpp @@ -230,7 +230,8 @@ nsCommandParams::GetOrMakeEntry(const char* aName, uint8_t entryType) return foundEntry; } - foundEntry = (HashEntry *)PL_DHashTableAdd(&mValuesHash, (void *)aName); + foundEntry = static_cast + (PL_DHashTableAdd(&mValuesHash, (void *)aName, fallible)); if (!foundEntry) { return nullptr; } diff --git a/gfx/thebes/gfxFT2FontList.cpp b/gfx/thebes/gfxFT2FontList.cpp index 471cdb5900cc..6acb34511cd8 100644 --- a/gfx/thebes/gfxFT2FontList.cpp +++ b/gfx/thebes/gfxFT2FontList.cpp @@ -687,9 +687,8 @@ public: } uint32_t filesize = strtoul(beginning, nullptr, 10); - FNCMapEntry* mapEntry = - static_cast - (PL_DHashTableAdd(&mMap, filename.get())); + FNCMapEntry* mapEntry = static_cast + (PL_DHashTableAdd(&mMap, filename.get(), fallible)); if (mapEntry) { mapEntry->mFilename.Assign(filename); mapEntry->mTimestamp = timestamp; @@ -736,9 +735,8 @@ public: if (!mMap.IsInitialized()) { return; } - FNCMapEntry* entry = - static_cast - (PL_DHashTableAdd(&mMap, aFileName.get())); + FNCMapEntry* entry = static_cast + (PL_DHashTableAdd(&mMap, aFileName.get(), fallible)); if (entry) { entry->mFilename.Assign(aFileName); entry->mTimestamp = aTimestamp; diff --git a/js/xpconnect/src/XPCMaps.cpp b/js/xpconnect/src/XPCMaps.cpp index d5c5b4f81e23..ad4339d42482 100644 --- a/js/xpconnect/src/XPCMaps.cpp +++ b/js/xpconnect/src/XPCMaps.cpp @@ -593,7 +593,8 @@ XPCNativeScriptableSharedMap::GetNewOrUsed(uint32_t flags, NS_PRECONDITION(si,"bad param"); XPCNativeScriptableShared key(flags, name); - Entry* entry = (Entry*) PL_DHashTableAdd(mTable, &key); + Entry* entry = static_cast + (PL_DHashTableAdd(mTable, &key, fallible)); if (!entry) return false; diff --git a/js/xpconnect/src/XPCMaps.h b/js/xpconnect/src/XPCMaps.h index 413fe93065b2..5a8f4720377c 100644 --- a/js/xpconnect/src/XPCMaps.h +++ b/js/xpconnect/src/XPCMaps.h @@ -120,7 +120,8 @@ public: NS_PRECONDITION(wrapper,"bad param"); nsISupports* obj = wrapper->GetIdentityObject(); MOZ_ASSERT(!Find(obj), "wrapper already in new scope!"); - Entry* entry = (Entry*) PL_DHashTableAdd(mTable, obj); + Entry* entry = static_cast + (PL_DHashTableAdd(mTable, obj, mozilla::fallible)); if (!entry) return nullptr; if (entry->key) @@ -185,7 +186,8 @@ public: { NS_PRECONDITION(clazz,"bad param"); const nsIID* iid = &clazz->GetIID(); - Entry* entry = (Entry*) PL_DHashTableAdd(mTable, iid); + Entry* entry = static_cast + (PL_DHashTableAdd(mTable, iid, mozilla::fallible)); if (!entry) return nullptr; if (entry->key) @@ -238,7 +240,8 @@ public: { NS_PRECONDITION(iface,"bad param"); const nsIID* iid = iface->GetIID(); - Entry* entry = (Entry*) PL_DHashTableAdd(mTable, iid); + Entry* entry = static_cast + (PL_DHashTableAdd(mTable, iid, mozilla::fallible)); if (!entry) return nullptr; if (entry->key) @@ -293,7 +296,8 @@ public: inline XPCNativeSet* Add(nsIClassInfo* info, XPCNativeSet* set) { NS_PRECONDITION(info,"bad param"); - Entry* entry = (Entry*) PL_DHashTableAdd(mTable, info); + Entry* entry = static_cast + (PL_DHashTableAdd(mTable, info, mozilla::fallible)); if (!entry) return nullptr; if (entry->key) @@ -349,7 +353,8 @@ public: inline XPCWrappedNativeProto* Add(nsIClassInfo* info, XPCWrappedNativeProto* proto) { NS_PRECONDITION(info,"bad param"); - Entry* entry = (Entry*) PL_DHashTableAdd(mTable, info); + Entry* entry = static_cast + (PL_DHashTableAdd(mTable, info, mozilla::fallible)); if (!entry) return nullptr; if (entry->key) @@ -411,7 +416,8 @@ public: { NS_PRECONDITION(key,"bad param"); NS_PRECONDITION(set,"bad param"); - Entry* entry = (Entry*) PL_DHashTableAdd(mTable, key); + Entry* entry = static_cast + (PL_DHashTableAdd(mTable, key, mozilla::fallible)); if (!entry) return nullptr; if (entry->key_value) @@ -483,8 +489,8 @@ public: inline nsIXPCFunctionThisTranslator* Add(REFNSIID iid, nsIXPCFunctionThisTranslator* obj) { - - Entry* entry = (Entry*) PL_DHashTableAdd(mTable, &iid); + Entry* entry = static_cast + (PL_DHashTableAdd(mTable, &iid, mozilla::fallible)); if (!entry) return nullptr; entry->value = obj; @@ -555,8 +561,8 @@ public: inline XPCWrappedNativeProto* Add(XPCWrappedNativeProto* proto) { NS_PRECONDITION(proto,"bad param"); - PLDHashEntryStub* entry = (PLDHashEntryStub*) - PL_DHashTableAdd(mTable, proto); + PLDHashEntryStub* entry = static_cast + (PL_DHashTableAdd(mTable, proto, mozilla::fallible)); if (!entry) return nullptr; if (entry->key) diff --git a/layout/base/nsFrameManager.cpp b/layout/base/nsFrameManager.cpp index d34d0e581655..7b43cffd5555 100644 --- a/layout/base/nsFrameManager.cpp +++ b/layout/base/nsFrameManager.cpp @@ -175,8 +175,9 @@ nsFrameManager::RegisterPlaceholderFrame(nsPlaceholderFrame* aPlaceholderFrame) PL_DHashTableInit(&mPlaceholderMap, &PlaceholderMapOps, sizeof(PlaceholderMapEntry)); } - PlaceholderMapEntry *entry = static_cast(PL_DHashTableAdd(&mPlaceholderMap, - aPlaceholderFrame->GetOutOfFlowFrame())); + PlaceholderMapEntry *entry = static_cast + (PL_DHashTableAdd(&mPlaceholderMap, + aPlaceholderFrame->GetOutOfFlowFrame(), fallible)); if (!entry) return NS_ERROR_OUT_OF_MEMORY; diff --git a/layout/style/nsCSSRuleProcessor.cpp b/layout/style/nsCSSRuleProcessor.cpp index a2126e266242..d6b0497df34e 100644 --- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -573,7 +573,7 @@ void RuleHash::AppendRuleToTable(PLDHashTable* aTable, const void* aKey, { // Get a new or existing entry. RuleHashTableEntry *entry = static_cast - (PL_DHashTableAdd(aTable, aKey)); + (PL_DHashTableAdd(aTable, aKey, fallible)); if (!entry) return; entry->mRules.AppendElement(RuleValue(aRuleInfo, mRuleCount++, mQuirksMode)); @@ -585,7 +585,7 @@ AppendRuleToTagTable(PLDHashTable* aTable, nsIAtom* aKey, { // Get a new or exisiting entry RuleHashTagTableEntry *entry = static_cast - (PL_DHashTableAdd(aTable, aKey)); + (PL_DHashTableAdd(aTable, aKey, fallible)); if (!entry) return; @@ -1041,7 +1041,7 @@ RuleCascadeData::AttributeListFor(nsIAtom* aAttribute) { AtomSelectorEntry *entry = static_cast - (PL_DHashTableAdd(&mAttributeSelectors, aAttribute)); + (PL_DHashTableAdd(&mAttributeSelectors, aAttribute, fallible)); if (!entry) return nullptr; return &entry->mSelectors; @@ -3134,9 +3134,8 @@ AddSelector(RuleCascadeData* aCascade, if (negation == aSelectorInTopLevel) { for (nsAtomList* curID = negation->mIDList; curID; curID = curID->mNext) { - AtomSelectorEntry *entry = - static_cast(PL_DHashTableAdd(&aCascade->mIdSelectors, - curID->mAtom)); + AtomSelectorEntry *entry = static_cast + (PL_DHashTableAdd(&aCascade->mIdSelectors, curID->mAtom, fallible)); if (entry) { entry->mSelectors.AppendElement(aSelectorInTopLevel); } @@ -3149,9 +3148,9 @@ AddSelector(RuleCascadeData* aCascade, if (negation == aSelectorInTopLevel) { for (nsAtomList* curClass = negation->mClassList; curClass; curClass = curClass->mNext) { - AtomSelectorEntry *entry = - static_cast(PL_DHashTableAdd(&aCascade->mClassSelectors, - curClass->mAtom)); + AtomSelectorEntry *entry = static_cast + (PL_DHashTableAdd(&aCascade->mClassSelectors, curClass->mAtom, + fallible)); if (entry) { entry->mSelectors.AppendElement(aSelectorInTopLevel); } @@ -3410,7 +3409,8 @@ CascadeRuleEnumFunc(css::Rule* aRule, void* aData) sel; sel = sel->mNext) { int32_t weight = sel->mWeight; RuleByWeightEntry *entry = static_cast( - PL_DHashTableAdd(&data->mRulesByWeight, NS_INT32_TO_PTR(weight))); + PL_DHashTableAdd(&data->mRulesByWeight, NS_INT32_TO_PTR(weight), + fallible)); if (!entry) return false; entry->data.mWeight = weight; diff --git a/layout/style/nsHTMLStyleSheet.cpp b/layout/style/nsHTMLStyleSheet.cpp index 47ead13ef41f..1e80cdcd90d1 100644 --- a/layout/style/nsHTMLStyleSheet.cpp +++ b/layout/style/nsHTMLStyleSheet.cpp @@ -483,8 +483,9 @@ nsHTMLStyleSheet::UniqueMappedAttributes(nsMappedAttributes* aMapped) PL_DHashTableInit(&mMappedAttrTable, &MappedAttrTable_Ops, sizeof(MappedAttrTableEntry)); } - MappedAttrTableEntry *entry = static_cast - (PL_DHashTableAdd(&mMappedAttrTable, aMapped)); + MappedAttrTableEntry *entry = + static_cast + (PL_DHashTableAdd(&mMappedAttrTable, aMapped, fallible)); if (!entry) return nullptr; if (!entry->mAttributes) { @@ -518,7 +519,7 @@ nsHTMLStyleSheet::LangRuleFor(const nsString& aLanguage) sizeof(LangRuleTableEntry)); } LangRuleTableEntry *entry = static_cast - (PL_DHashTableAdd(&mLangRuleTable, &aLanguage)); + (PL_DHashTableAdd(&mLangRuleTable, &aLanguage, fallible)); if (!entry) { NS_ASSERTION(false, "out of memory"); return nullptr; diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index f7831ee60255..78c7c6150e99 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -1535,7 +1535,7 @@ nsRuleNode::Transition(nsIStyleRule* aRule, uint8_t aLevel, if (ChildrenAreHashed()) { ChildrenHashEntry *entry = static_cast - (PL_DHashTableAdd(ChildrenHash(), &key)); + (PL_DHashTableAdd(ChildrenHash(), &key, fallible)); if (!entry) { NS_WARNING("out of memory"); return this; @@ -1611,7 +1611,7 @@ nsRuleNode::ConvertChildrenToHash(int32_t aNumKids) for (nsRuleNode* curr = ChildrenList(); curr; curr = curr->mNextSibling) { // This will never fail because of the initial size we gave the table. ChildrenHashEntry *entry = static_cast( - PL_DHashTableAdd(hash, curr->mRule)); + PL_DHashTableAdd(hash, curr->mRule, fallible)); NS_ASSERTION(!entry->mRuleNode, "duplicate entries in list"); entry->mRuleNode = curr; } diff --git a/layout/tables/SpanningCellSorter.cpp b/layout/tables/SpanningCellSorter.cpp index 8a4c015cb28f..63bc700bc4c9 100644 --- a/layout/tables/SpanningCellSorter.cpp +++ b/layout/tables/SpanningCellSorter.cpp @@ -75,7 +75,8 @@ SpanningCellSorter::AddCell(int32_t aColSpan, int32_t aRow, int32_t aCol) sizeof(HashTableEntry)); } HashTableEntry *entry = static_cast - (PL_DHashTableAdd(&mHashTable, NS_INT32_TO_PTR(aColSpan))); + (PL_DHashTableAdd(&mHashTable, NS_INT32_TO_PTR(aColSpan), + fallible)); NS_ENSURE_TRUE(entry, false); NS_ASSERTION(entry->mColSpan == 0 || entry->mColSpan == aColSpan, diff --git a/modules/libpref/prefapi.cpp b/modules/libpref/prefapi.cpp index 00f3079a6bdd..475791a02841 100644 --- a/modules/libpref/prefapi.cpp +++ b/modules/libpref/prefapi.cpp @@ -735,7 +735,8 @@ nsresult pref_HashPref(const char *key, PrefValue value, PrefType type, uint32_t if (!gHashTable.IsInitialized()) return NS_ERROR_OUT_OF_MEMORY; - PrefHashEntry* pref = static_cast(PL_DHashTableAdd(&gHashTable, key)); + PrefHashEntry* pref = static_cast + (PL_DHashTableAdd(&gHashTable, key, fallible)); if (!pref) return NS_ERROR_OUT_OF_MEMORY; diff --git a/netwerk/base/nsLoadGroup.cpp b/netwerk/base/nsLoadGroup.cpp index f9566558dbab..4fd4075013d6 100644 --- a/netwerk/base/nsLoadGroup.cpp +++ b/netwerk/base/nsLoadGroup.cpp @@ -511,9 +511,8 @@ nsLoadGroup::AddRequest(nsIRequest *request, nsISupports* ctxt) // Add the request to the list of active requests... // - RequestMapEntry *entry = - static_cast - (PL_DHashTableAdd(&mRequests, request)); + RequestMapEntry *entry = static_cast + (PL_DHashTableAdd(&mRequests, request, fallible)); if (!entry) { return NS_ERROR_OUT_OF_MEMORY; diff --git a/netwerk/cache/nsCacheEntry.cpp b/netwerk/cache/nsCacheEntry.cpp index 46dcdf87034a..2e9d50355b63 100644 --- a/netwerk/cache/nsCacheEntry.cpp +++ b/netwerk/cache/nsCacheEntry.cpp @@ -435,7 +435,7 @@ nsCacheEntryHashTable::AddEntry( nsCacheEntry *cacheEntry) if (!table.IsInitialized()) return NS_ERROR_NOT_INITIALIZED; if (!cacheEntry) return NS_ERROR_NULL_POINTER; - hashEntry = PL_DHashTableAdd(&table, &(cacheEntry->mKey)); + hashEntry = PL_DHashTableAdd(&table, &(cacheEntry->mKey), fallible); #ifndef DEBUG_dougt NS_ASSERTION(((nsCacheEntryHashTableEntry *)hashEntry)->cacheEntry == 0, "### nsCacheEntryHashTable::AddEntry - entry already used"); diff --git a/netwerk/cache/nsDiskCacheBinding.cpp b/netwerk/cache/nsDiskCacheBinding.cpp index ae735d7e05bb..637bb732a8c0 100644 --- a/netwerk/cache/nsDiskCacheBinding.cpp +++ b/netwerk/cache/nsDiskCacheBinding.cpp @@ -236,7 +236,8 @@ nsDiskCacheBindery::AddBinding(nsDiskCacheBinding * binding) HashTableEntry * hashEntry; hashEntry = (HashTableEntry *) PL_DHashTableAdd(&table, - (void *)(uintptr_t) binding->mRecord.HashNumber()); + (void *)(uintptr_t) binding->mRecord.HashNumber(), + fallible); if (!hashEntry) return NS_ERROR_OUT_OF_MEMORY; if (hashEntry->mBinding == nullptr) { diff --git a/netwerk/dns/nsHostResolver.cpp b/netwerk/dns/nsHostResolver.cpp index f238294fe080..79fa275d7249 100644 --- a/netwerk/dns/nsHostResolver.cpp +++ b/netwerk/dns/nsHostResolver.cpp @@ -764,7 +764,7 @@ nsHostResolver::ResolveHost(const char *host, nsHostKey key = { host, flags, af }; nsHostDBEnt *he = static_cast - (PL_DHashTableAdd(&mDB, &key)); + (PL_DHashTableAdd(&mDB, &key, fallible)); // if the record is null, the hash table OOM'd. if (!he) { diff --git a/netwerk/protocol/http/nsHttp.cpp b/netwerk/protocol/http/nsHttp.cpp index 79eeb3c6ee71..43f014ab0c62 100644 --- a/netwerk/protocol/http/nsHttp.cpp +++ b/netwerk/protocol/http/nsHttp.cpp @@ -118,7 +118,7 @@ nsHttp::CreateAtomTable() for (int i = 0; atoms[i]; ++i) { PLDHashEntryStub *stub = reinterpret_cast - (PL_DHashTableAdd(&sAtomTable, atoms[i])); + (PL_DHashTableAdd(&sAtomTable, atoms[i], fallible)); if (!stub) return NS_ERROR_OUT_OF_MEMORY; @@ -166,7 +166,7 @@ nsHttp::ResolveAtom(const char *str) MutexAutoLock lock(*sLock); PLDHashEntryStub *stub = reinterpret_cast - (PL_DHashTableAdd(&sAtomTable, str)); + (PL_DHashTableAdd(&sAtomTable, str, fallible)); if (!stub) return atom; // out of memory diff --git a/parser/htmlparser/nsHTMLEntities.cpp b/parser/htmlparser/nsHTMLEntities.cpp index 74bfc3eb8888..84138fc6f68d 100644 --- a/parser/htmlparser/nsHTMLEntities.cpp +++ b/parser/htmlparser/nsHTMLEntities.cpp @@ -94,7 +94,7 @@ nsHTMLEntities::AddRefTable(void) // add to Entity->Unicode table EntityNodeEntry* entry = static_cast - (PL_DHashTableAdd(&gEntityToUnicode, node->mStr)); + (PL_DHashTableAdd(&gEntityToUnicode, node->mStr, fallible)); NS_ASSERTION(entry, "Error adding an entry"); // Prefer earlier entries when we have duplication. if (!entry->node) @@ -103,7 +103,8 @@ nsHTMLEntities::AddRefTable(void) // add to Unicode->Entity table entry = static_cast (PL_DHashTableAdd(&gUnicodeToEntity, - NS_INT32_TO_PTR(node->mUnicode))); + NS_INT32_TO_PTR(node->mUnicode), + fallible)); NS_ASSERTION(entry, "Error adding an entry"); // Prefer earlier entries when we have duplication. if (!entry->node) diff --git a/rdf/base/nsInMemoryDataSource.cpp b/rdf/base/nsInMemoryDataSource.cpp index 61a3fc07880f..04be3ade4d8d 100644 --- a/rdf/base/nsInMemoryDataSource.cpp +++ b/rdf/base/nsInMemoryDataSource.cpp @@ -334,7 +334,8 @@ public: void SetForwardArcs(nsIRDFResource* u, Assertion* as) { if (as) { - Entry* entry = static_cast(PL_DHashTableAdd(&mForwardArcs, u)); + Entry* entry = static_cast + (PL_DHashTableAdd(&mForwardArcs, u, mozilla::fallible)); if (entry) { entry->mNode = u; entry->mAssertions = as; @@ -348,7 +349,8 @@ public: void SetReverseArcs(nsIRDFNode* v, Assertion* as) { if (as) { - Entry* entry = static_cast(PL_DHashTableAdd(&mReverseArcs, v)); + Entry* entry = static_cast + (PL_DHashTableAdd(&mReverseArcs, v, mozilla::fallible)); if (entry) { entry->mNode = v; entry->mAssertions = as; @@ -1186,7 +1188,8 @@ InMemoryDataSource::LockedAssert(nsIRDFResource* aSource, } else { - hdr = PL_DHashTableAdd(next->u.hash.mPropertyHash, aProperty); + hdr = PL_DHashTableAdd(next->u.hash.mPropertyHash, aProperty, + mozilla::fallible); if (hdr) { Entry* entry = static_cast(hdr); @@ -1297,8 +1300,9 @@ InMemoryDataSource::LockedUnassert(nsIRDFResource* aSource, PL_DHashTableRawRemove(root->u.hash.mPropertyHash, hdr); if (next && next->mNext) { - PLDHashEntryHdr* hdr = PL_DHashTableAdd(root->u.hash.mPropertyHash, - aProperty); + PLDHashEntryHdr* hdr = + PL_DHashTableAdd(root->u.hash.mPropertyHash, aProperty, + mozilla::fallible); if (hdr) { Entry* entry = static_cast(hdr); entry->mNode = aProperty; @@ -1742,7 +1746,8 @@ InMemoryDataSource::EnsureFastContainment(nsIRDFResource* aSource) val->mNext = first; } else { - PLDHashEntryHdr* hdr = PL_DHashTableAdd(table, prop); + PLDHashEntryHdr* hdr = PL_DHashTableAdd(table, prop, + mozilla::fallible); if (hdr) { Entry* entry = static_cast(hdr); entry->mNode = prop; diff --git a/rdf/base/nsRDFService.cpp b/rdf/base/nsRDFService.cpp index ffce7a6cad3d..1d539d395f19 100644 --- a/rdf/base/nsRDFService.cpp +++ b/rdf/base/nsRDFService.cpp @@ -1162,7 +1162,7 @@ RDFServiceImpl::RegisterResource(nsIRDFResource* aResource, bool aReplace) aResource, (const char*) uri)); } else { - hdr = PL_DHashTableAdd(&mResources, uri); + hdr = PL_DHashTableAdd(&mResources, uri, fallible); if (! hdr) return NS_ERROR_OUT_OF_MEMORY; @@ -1399,7 +1399,7 @@ RDFServiceImpl::RegisterLiteral(nsIRDFLiteral* aLiteral) NS_ASSERTION(!PL_DHashTableSearch(&mLiterals, value), "literal already registered"); - PLDHashEntryHdr *hdr = PL_DHashTableAdd(&mLiterals, value); + PLDHashEntryHdr *hdr = PL_DHashTableAdd(&mLiterals, value, fallible); if (! hdr) return NS_ERROR_OUT_OF_MEMORY; @@ -1451,7 +1451,7 @@ RDFServiceImpl::RegisterInt(nsIRDFInt* aInt) NS_ASSERTION(!PL_DHashTableSearch(&mInts, &value), "int already registered"); - PLDHashEntryHdr *hdr = PL_DHashTableAdd(&mInts, &value); + PLDHashEntryHdr *hdr = PL_DHashTableAdd(&mInts, &value, fallible); if (! hdr) return NS_ERROR_OUT_OF_MEMORY; @@ -1503,7 +1503,7 @@ RDFServiceImpl::RegisterDate(nsIRDFDate* aDate) NS_ASSERTION(!PL_DHashTableSearch(&mDates, &value), "date already registered"); - PLDHashEntryHdr *hdr = PL_DHashTableAdd(&mDates, &value); + PLDHashEntryHdr *hdr = PL_DHashTableAdd(&mDates, &value, fallible); if (! hdr) return NS_ERROR_OUT_OF_MEMORY; @@ -1550,7 +1550,7 @@ RDFServiceImpl::RegisterBlob(BlobImpl *aBlob) NS_ASSERTION(!PL_DHashTableSearch(&mBlobs, &aBlob->mData), "blob already registered"); - PLDHashEntryHdr *hdr = PL_DHashTableAdd(&mBlobs, &aBlob->mData); + PLDHashEntryHdr *hdr = PL_DHashTableAdd(&mBlobs, &aBlob->mData, fallible); if (! hdr) return NS_ERROR_OUT_OF_MEMORY; diff --git a/security/manager/boot/src/nsSecureBrowserUIImpl.cpp b/security/manager/boot/src/nsSecureBrowserUIImpl.cpp index a5b6bd9907db..0d5354ea3daf 100644 --- a/security/manager/boot/src/nsSecureBrowserUIImpl.cpp +++ b/security/manager/boot/src/nsSecureBrowserUIImpl.cpp @@ -862,8 +862,8 @@ nsSecureBrowserUIImpl::OnStateChange(nsIWebProgress* aWebProgress, // means, there has already been data transfered. ReentrantMonitorAutoEnter lock(mReentrantMonitor); - PL_DHashTableAdd(&mTransferringRequests, aRequest); - + PL_DHashTableAdd(&mTransferringRequests, aRequest, fallible); + return NS_OK; } diff --git a/security/manager/ssl/src/nsCertTree.cpp b/security/manager/ssl/src/nsCertTree.cpp index 2de29024414a..3f5e8c860bbf 100644 --- a/security/manager/ssl/src/nsCertTree.cpp +++ b/security/manager/ssl/src/nsCertTree.cpp @@ -201,9 +201,8 @@ CompareCacheHashEntry * nsCertTree::getCacheEntry(void *cache, void *aCert) { PLDHashTable &aCompareCache = *reinterpret_cast(cache); - CompareCacheHashEntryPtr *entryPtr = - static_cast - (PL_DHashTableAdd(&aCompareCache, aCert)); + CompareCacheHashEntryPtr *entryPtr = static_cast + (PL_DHashTableAdd(&aCompareCache, aCert, fallible)); return entryPtr ? entryPtr->entry : nullptr; } diff --git a/security/manager/ssl/src/nsNSSShutDown.cpp b/security/manager/ssl/src/nsNSSShutDown.cpp index f20490673ae1..5c4605edb5c6 100644 --- a/security/manager/ssl/src/nsNSSShutDown.cpp +++ b/security/manager/ssl/src/nsNSSShutDown.cpp @@ -70,7 +70,7 @@ void nsNSSShutDownList::remember(nsNSSShutDownObject *o) PR_ASSERT(o); MutexAutoLock lock(singleton->mListLock); - PL_DHashTableAdd(&singleton->mObjects, o); + PL_DHashTableAdd(&singleton->mObjects, o, fallible); } void nsNSSShutDownList::forget(nsNSSShutDownObject *o) @@ -90,7 +90,7 @@ void nsNSSShutDownList::remember(nsOnPK11LogoutCancelObject *o) PR_ASSERT(o); MutexAutoLock lock(singleton->mListLock); - PL_DHashTableAdd(&singleton->mPK11LogoutCancelObjects, o); + PL_DHashTableAdd(&singleton->mPK11LogoutCancelObjects, o, fallible); } void nsNSSShutDownList::forget(nsOnPK11LogoutCancelObject *o) diff --git a/uriloader/base/nsDocLoader.cpp b/uriloader/base/nsDocLoader.cpp index ae724bc34baa..3e6252beaa8a 100644 --- a/uriloader/base/nsDocLoader.cpp +++ b/uriloader/base/nsDocLoader.cpp @@ -1340,7 +1340,7 @@ nsDocLoader::RefreshAttempted(nsIWebProgress* aWebProgress, nsresult nsDocLoader::AddRequestInfo(nsIRequest *aRequest) { - if (!PL_DHashTableAdd(&mRequestInfoHash, aRequest)) { + if (!PL_DHashTableAdd(&mRequestInfoHash, aRequest, mozilla::fallible)) { return NS_ERROR_OUT_OF_MEMORY; } diff --git a/xpcom/base/nsCycleCollector.cpp b/xpcom/base/nsCycleCollector.cpp index 30077dd8ed3a..594567f3ccca 100644 --- a/xpcom/base/nsCycleCollector.cpp +++ b/xpcom/base/nsCycleCollector.cpp @@ -900,8 +900,8 @@ PtrToNodeEntry* CCGraph::AddNodeToMap(void* aPtr) { JS::AutoSuppressGCAnalysis suppress; - PtrToNodeEntry* e = - static_cast(PL_DHashTableAdd(&mPtrToNodeMap, aPtr)); + PtrToNodeEntry* e = static_cast + (PL_DHashTableAdd(&mPtrToNodeMap, aPtr, fallible)); if (!e) { // Caller should track OOMs return nullptr; diff --git a/xpcom/ds/nsAtomTable.cpp b/xpcom/ds/nsAtomTable.cpp index ae3bda994ad4..7bdc13a0aa68 100644 --- a/xpcom/ds/nsAtomTable.cpp +++ b/xpcom/ds/nsAtomTable.cpp @@ -556,12 +556,8 @@ GetAtomHashEntry(const char* aString, uint32_t aLength, uint32_t* aHashOut) MOZ_ASSERT(NS_IsMainThread(), "wrong thread"); EnsureTableExists(); AtomTableKey key(aString, aLength, aHashOut); - AtomTableEntry* e = static_cast( - PL_DHashTableAdd(&gAtomTable, &key)); - if (!e) { - NS_ABORT_OOM(gAtomTable.EntryCount() * gAtomTable.EntrySize()); - } - return e; + // This is an infallible add. + return static_cast(PL_DHashTableAdd(&gAtomTable, &key)); } static inline AtomTableEntry* @@ -570,12 +566,8 @@ GetAtomHashEntry(const char16_t* aString, uint32_t aLength, uint32_t* aHashOut) MOZ_ASSERT(NS_IsMainThread(), "wrong thread"); EnsureTableExists(); AtomTableKey key(aString, aLength, aHashOut); - AtomTableEntry* e = static_cast( - PL_DHashTableAdd(&gAtomTable, &key)); - if (!e) { - NS_ABORT_OOM(gAtomTable.EntryCount() * gAtomTable.EntrySize()); - } - return e; + // This is an infallible add. + return static_cast(PL_DHashTableAdd(&gAtomTable, &key)); } class CheckStaticAtomSizes diff --git a/xpcom/ds/nsPersistentProperties.cpp b/xpcom/ds/nsPersistentProperties.cpp index 8584fa0d9194..e99675593850 100644 --- a/xpcom/ds/nsPersistentProperties.cpp +++ b/xpcom/ds/nsPersistentProperties.cpp @@ -528,7 +528,7 @@ nsPersistentProperties::SetStringProperty(const nsACString& aKey, { const nsAFlatCString& flatKey = PromiseFlatCString(aKey); PropertyTableEntry* entry = static_cast( - PL_DHashTableAdd(&mTable, flatKey.get())); + PL_DHashTableAdd(&mTable, flatKey.get(), mozilla::fallible)); if (entry->mKey) { aOldValue = entry->mValue; diff --git a/xpcom/ds/nsStaticNameTable.cpp b/xpcom/ds/nsStaticNameTable.cpp index db5091e8fac6..d057b1233f5d 100644 --- a/xpcom/ds/nsStaticNameTable.cpp +++ b/xpcom/ds/nsStaticNameTable.cpp @@ -161,8 +161,8 @@ nsStaticCaseInsensitiveNameTable::Init(const char* const aNames[], NameTableKey key(strPtr); - NameTableEntry* entry = - static_cast(PL_DHashTableAdd(&mNameTable, &key)); + NameTableEntry* entry = static_cast + (PL_DHashTableAdd(&mNameTable, &key, fallible)); if (!entry) { continue; } diff --git a/xpcom/glue/nsTHashtable.h b/xpcom/glue/nsTHashtable.h index 2a0d5dc5e0d4..cd582d8f0e17 100644 --- a/xpcom/glue/nsTHashtable.h +++ b/xpcom/glue/nsTHashtable.h @@ -149,19 +149,21 @@ public: */ EntryType* PutEntry(KeyType aKey) { - EntryType* e = PutEntry(aKey, mozilla::fallible); - if (!e) { - NS_ABORT_OOM(mTable.EntrySize() * mTable.EntryCount()); - } - return e; - } - - EntryType* PutEntry(KeyType aKey, const fallible_t&) NS_WARN_UNUSED_RESULT { NS_ASSERTION(mTable.IsInitialized(), "nsTHashtable was not initialized properly."); - return static_cast(PL_DHashTableAdd( - &mTable, EntryType::KeyToPointer(aKey))); + return static_cast // infallible add + (PL_DHashTableAdd(&mTable, EntryType::KeyToPointer(aKey))); + } + + EntryType* PutEntry(KeyType aKey, const fallible_t&) NS_WARN_UNUSED_RESULT + { + NS_ASSERTION(mTable.IsInitialized(), + "nsTHashtable was not initialized properly."); + + return static_cast + (PL_DHashTableAdd(&mTable, EntryType::KeyToPointer(aKey), + mozilla::fallible)); } /** diff --git a/xpcom/glue/pldhash.cpp b/xpcom/glue/pldhash.cpp index d284d1ec2428..62fa59ccdf57 100644 --- a/xpcom/glue/pldhash.cpp +++ b/xpcom/glue/pldhash.cpp @@ -529,7 +529,7 @@ PLDHashTable::Search(const void* aKey) } MOZ_ALWAYS_INLINE PLDHashEntryHdr* -PLDHashTable::Add(const void* aKey) +PLDHashTable::Add(const void* aKey, const mozilla::fallible_t&) { PLDHashNumber keyHash; PLDHashEntryHdr* entry; @@ -647,10 +647,24 @@ PL_DHashTableSearch(PLDHashTable* aTable, const void* aKey) return aTable->Search(aKey); } +PLDHashEntryHdr* PL_DHASH_FASTCALL +PL_DHashTableAdd(PLDHashTable* aTable, const void* aKey, + const fallible_t& aFallible) +{ + return aTable->Add(aKey, aFallible); +} + PLDHashEntryHdr* PL_DHASH_FASTCALL PL_DHashTableAdd(PLDHashTable* aTable, const void* aKey) { - return aTable->Add(aKey); + PLDHashEntryHdr* entry = PL_DHashTableAdd(aTable, aKey, fallible); + if (!entry) { + // There are two ways the Add could fail: (a) a entry storage reallocation + // failed, or (b) mOps->initEntry failed. The number we're reporting here + // is the one for case (a), which is the more likely of the two. + NS_ABORT_OOM(aTable->EntrySize() * aTable->EntryCount()); + } + return entry; } void PL_DHASH_FASTCALL diff --git a/xpcom/glue/pldhash.h b/xpcom/glue/pldhash.h index e820aa067a9d..a549c3cebeb8 100644 --- a/xpcom/glue/pldhash.h +++ b/xpcom/glue/pldhash.h @@ -10,6 +10,7 @@ * Double hashing, a la Knuth 6. */ #include "mozilla/Attributes.h" // for MOZ_ALWAYS_INLINE +#include "mozilla/fallible.h" #include "mozilla/MemoryReporting.h" #include "mozilla/Types.h" #include "nscore.h" @@ -244,7 +245,7 @@ public: void Finish(); PLDHashEntryHdr* Search(const void* aKey); - PLDHashEntryHdr* Add(const void* aKey); + PLDHashEntryHdr* Add(const void* aKey, const mozilla::fallible_t&); void Remove(const void* aKey); void RawRemove(PLDHashEntryHdr* aEntry); @@ -466,7 +467,7 @@ PL_DHashTableSearch(PLDHashTable* aTable, const void* aKey); /* * To add an entry identified by key to table, call: * - * entry = PL_DHashTableAdd(table, key); + * entry = PL_DHashTableAdd(table, key, mozilla::fallible); * * If entry is null upon return, then either (a) the table is severely * overloaded and memory can't be allocated for entry storage, or (b) @@ -480,6 +481,14 @@ PL_DHashTableSearch(PLDHashTable* aTable, const void* aKey); * optional initEntry hook was not used). */ PLDHashEntryHdr* PL_DHASH_FASTCALL +PL_DHashTableAdd(PLDHashTable* aTable, const void* aKey, + const mozilla::fallible_t&); + +/* + * This is like the other PL_DHashTableAdd() function, but infallible, and so + * never returns null. + */ +PLDHashEntryHdr* PL_DHASH_FASTCALL PL_DHashTableAdd(PLDHashTable* aTable, const void* aKey); /* diff --git a/xpcom/tests/TestPLDHash.cpp b/xpcom/tests/TestPLDHash.cpp index 3b56e367b62e..83851217c36b 100644 --- a/xpcom/tests/TestPLDHash.cpp +++ b/xpcom/tests/TestPLDHash.cpp @@ -139,7 +139,7 @@ static bool test_pldhash_grow_to_max_capacity() // Keep inserting elements until failure occurs because the table is full. size_t numInserted = 0; while (true) { - if (!PL_DHashTableAdd(&t, (const void*)numInserted)) { + if (!PL_DHashTableAdd(&t, (const void*)numInserted, mozilla::fallible)) { break; } numInserted++; From 66223ceeb0ee4d5623547936305800b5103e5c9f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 2 Feb 2015 23:58:42 -0800 Subject: [PATCH 39/74] Bug 1050035 (part 5) - Make CCGraphBuilder::AddNode() infallible. r=mccr8. --HG-- extra : rebase_source : 4ebe842e419f8b887b9e9b98f97c17fe103039bc --- xpcom/base/nsCycleCollector.cpp | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/xpcom/base/nsCycleCollector.cpp b/xpcom/base/nsCycleCollector.cpp index 594567f3ccca..a8f94a25a969 100644 --- a/xpcom/base/nsCycleCollector.cpp +++ b/xpcom/base/nsCycleCollector.cpp @@ -900,13 +900,8 @@ PtrToNodeEntry* CCGraph::AddNodeToMap(void* aPtr) { JS::AutoSuppressGCAnalysis suppress; - PtrToNodeEntry* e = static_cast - (PL_DHashTableAdd(&mPtrToNodeMap, aPtr, fallible)); - if (!e) { - // Caller should track OOMs - return nullptr; - } - return e; + return static_cast + (PL_DHashTableAdd(&mPtrToNodeMap, aPtr)); // infallible add } void @@ -2037,7 +2032,6 @@ private: nsCString mNextEdgeName; nsCOMPtr mListener; bool mMergeZones; - bool mRanOutOfMemory; nsAutoPtr mCurrNode; public: @@ -2152,7 +2146,6 @@ CCGraphBuilder::CCGraphBuilder(CCGraph& aGraph, , mJSZoneParticipant(nullptr) , mListener(aListener) , mMergeZones(aMergeZones) - , mRanOutOfMemory(false) { if (aJSRuntime) { mJSParticipant = aJSRuntime->GCThingParticipant(); @@ -2186,11 +2179,6 @@ PtrInfo* CCGraphBuilder::AddNode(void* aPtr, nsCycleCollectionParticipant* aParticipant) { PtrToNodeEntry* e = mGraph.AddNodeToMap(aPtr); - if (!e) { - mRanOutOfMemory = true; - return nullptr; - } - PtrInfo* result; if (!e->mNode) { // New entry. @@ -2271,11 +2259,6 @@ CCGraphBuilder::BuildGraph(SliceBudget& aBudget) SetLastChild(); } - if (mRanOutOfMemory) { - MOZ_ASSERT(false, "Ran out of memory while building cycle collector graph"); - CC_TELEMETRY(_OOM, true); - } - mCurrNode = nullptr; return true; From 5533ff3254812ea26b354e16f085448ce937ad75 Mon Sep 17 00:00:00 2001 From: Jeff Gilbert Date: Wed, 4 Feb 2015 15:07:32 -0800 Subject: [PATCH 40/74] Bug 1129213 - Support non-UINT32_MAX initial values for STENCIL_VALUE_MASK. - r=kamidphish --- dom/canvas/WebGLContextUtils.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/dom/canvas/WebGLContextUtils.cpp b/dom/canvas/WebGLContextUtils.cpp index 798ffcf00c8c..b0e02a185770 100644 --- a/dom/canvas/WebGLContextUtils.cpp +++ b/dom/canvas/WebGLContextUtils.cpp @@ -1123,8 +1123,15 @@ WebGLContext::AssertCachedState() AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_REF, stencilRefMask, mStencilRefFront); AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_REF, stencilRefMask, mStencilRefBack); - AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_VALUE_MASK, mStencilValueMaskFront); - AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_VALUE_MASK, mStencilValueMaskBack); + // GLES 3.0.4, $4.1.4, p177: + // [...] the front and back stencil mask are both set to the value `2^s - 1`, where + // `s` is greater than or equal to the number of bits in the deepest stencil buffer + // supported by the GL implementation. + const int maxStencilBits = 8; + const GLuint maxStencilBitsMask = (1 << maxStencilBits) - 1; + + AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_VALUE_MASK, maxStencilBitsMask, mStencilValueMaskFront); + AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_VALUE_MASK, maxStencilBitsMask, mStencilValueMaskBack); AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_WRITEMASK, mStencilWriteMaskFront); AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_WRITEMASK, mStencilWriteMaskBack); From f4c131136e62e0f3c9c820c1b8b089f62d69105c Mon Sep 17 00:00:00 2001 From: Andrew McCreight Date: Wed, 4 Feb 2015 15:15:12 -0800 Subject: [PATCH 41/74] Bug 1127430, part 1 - Tuck more braces in nsWebBrowser. r=smaug --- embedding/browser/nsWebBrowser.cpp | 229 +++++++++++------------------ embedding/browser/nsWebBrowser.h | 7 +- 2 files changed, 91 insertions(+), 145 deletions(-) diff --git a/embedding/browser/nsWebBrowser.cpp b/embedding/browser/nsWebBrowser.cpp index 03711c57b1dc..23b815535498 100644 --- a/embedding/browser/nsWebBrowser.cpp +++ b/embedding/browser/nsWebBrowser.cpp @@ -143,16 +143,18 @@ NS_IMETHODIMP nsWebBrowser::GetInterface(const nsIID& aIID, void** aSink) { NS_ENSURE_ARG_POINTER(aSink); - if (NS_SUCCEEDED(QueryInterface(aIID, aSink))) + if (NS_SUCCEEDED(QueryInterface(aIID, aSink))) { return NS_OK; + } if (mDocShell) { #ifdef NS_PRINTING if (aIID.Equals(NS_GET_IID(nsIWebBrowserPrint))) { nsCOMPtr viewer; mDocShell->GetContentViewer(getter_AddRefs(viewer)); - if (!viewer) + if (!viewer) { return NS_NOINTERFACE; + } nsCOMPtr webBrowserPrint(do_QueryInterface(viewer)); nsIWebBrowserPrint* print = (nsIWebBrowserPrint*)webBrowserPrint.get(); @@ -369,12 +371,11 @@ NS_IMETHODIMP nsWebBrowser::GetName(nsAString& aName) NS_IMETHODIMP nsWebBrowser::SetName(const nsAString& aName) { - if (mDocShell) - { + if (mDocShell) { return mDocShell->SetName(aName); - } - else + } else { mInitInfo->name = aName; + } return NS_OK; } @@ -383,12 +384,11 @@ NS_IMETHODIMP nsWebBrowser::NameEquals(const char16_t *aName, bool *_retval) { NS_ENSURE_ARG_POINTER(aName); NS_ENSURE_ARG_POINTER(_retval); - if (mDocShell) - { + if (mDocShell) { return mDocShell->NameEquals(aName, _retval); - } - else + } else { *_retval = mInitInfo->name.Equals(aName); + } return NS_OK; } @@ -411,10 +411,12 @@ NS_IMETHODIMP nsWebBrowser::SetItemType(int32_t aItemType) { NS_ENSURE_TRUE((aItemType == typeContentWrapper || aItemType == typeChromeWrapper), NS_ERROR_FAILURE); mContentType = aItemType; - if (mDocShell) + if (mDocShell) { mDocShell->SetItemType(mContentType == typeChromeWrapper ? static_cast(typeChrome) : static_cast(typeContent)); + } + return NS_OK; } @@ -492,14 +494,10 @@ NS_IMETHODIMP nsWebBrowser::GetTreeOwner(nsIDocShellTreeOwner** aTreeOwner) { NS_ENSURE_ARG_POINTER(aTreeOwner); *aTreeOwner = nullptr; - if (mDocShellTreeOwner) - { - if (mDocShellTreeOwner->mTreeOwner) - { + if (mDocShellTreeOwner) { + if (mDocShellTreeOwner->mTreeOwner) { *aTreeOwner = mDocShellTreeOwner->mTreeOwner; - } - else - { + } else { *aTreeOwner = mDocShellTreeOwner; } } @@ -788,16 +786,13 @@ NS_IMETHODIMP nsWebBrowser::SetProperty(uint32_t aId, uint32_t aValue) /* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long aStateFlags, in nsresult aStatus); */ NS_IMETHODIMP nsWebBrowser::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t aStateFlags, nsresult aStatus) { - if (mPersist) - { + if (mPersist) { mPersist->GetCurrentState(&mPersistCurrentState); } - if (aStateFlags & STATE_IS_NETWORK && aStateFlags & STATE_STOP) - { + if (aStateFlags & STATE_IS_NETWORK && aStateFlags & STATE_STOP) { mPersist = nullptr; } - if (mProgressListener) - { + if (mProgressListener) { return mProgressListener->OnStateChange(aWebProgress, aRequest, aStateFlags, aStatus); } return NS_OK; @@ -806,12 +801,10 @@ NS_IMETHODIMP nsWebBrowser::OnStateChange(nsIWebProgress *aWebProgress, nsIReque /* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */ NS_IMETHODIMP nsWebBrowser::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, int32_t aCurSelfProgress, int32_t aMaxSelfProgress, int32_t aCurTotalProgress, int32_t aMaxTotalProgress) { - if (mPersist) - { + if (mPersist) { mPersist->GetCurrentState(&mPersistCurrentState); } - if (mProgressListener) - { + if (mProgressListener) { return mProgressListener->OnProgressChange(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress); } return NS_OK; @@ -820,8 +813,7 @@ NS_IMETHODIMP nsWebBrowser::OnProgressChange(nsIWebProgress *aWebProgress, nsIRe /* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location, in unsigned long aFlags); */ NS_IMETHODIMP nsWebBrowser::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location, uint32_t aFlags) { - if (mProgressListener) - { + if (mProgressListener) { return mProgressListener->OnLocationChange(aWebProgress, aRequest, location, aFlags); } return NS_OK; @@ -830,8 +822,7 @@ NS_IMETHODIMP nsWebBrowser::OnLocationChange(nsIWebProgress *aWebProgress, nsIRe /* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */ NS_IMETHODIMP nsWebBrowser::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const char16_t *aMessage) { - if (mProgressListener) - { + if (mProgressListener) { return mProgressListener->OnStatusChange(aWebProgress, aRequest, aStatus, aMessage); } return NS_OK; @@ -840,8 +831,7 @@ NS_IMETHODIMP nsWebBrowser::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequ /* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */ NS_IMETHODIMP nsWebBrowser::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t state) { - if (mProgressListener) - { + if (mProgressListener) { return mProgressListener->OnSecurityChange(aWebProgress, aRequest, state); } return NS_OK; @@ -856,8 +846,7 @@ NS_IMETHODIMP nsWebBrowser::GetPersistFlags(uint32_t *aPersistFlags) { NS_ENSURE_ARG_POINTER(aPersistFlags); nsresult rv = NS_OK; - if (mPersist) - { + if (mPersist) { rv = mPersist->GetPersistFlags(&mPersistFlags); } *aPersistFlags = mPersistFlags; @@ -867,8 +856,7 @@ NS_IMETHODIMP nsWebBrowser::SetPersistFlags(uint32_t aPersistFlags) { nsresult rv = NS_OK; mPersistFlags = aPersistFlags; - if (mPersist) - { + if (mPersist) { rv = mPersist->SetPersistFlags(mPersistFlags); mPersist->GetPersistFlags(&mPersistFlags); } @@ -880,8 +868,7 @@ NS_IMETHODIMP nsWebBrowser::SetPersistFlags(uint32_t aPersistFlags) NS_IMETHODIMP nsWebBrowser::GetCurrentState(uint32_t *aCurrentState) { NS_ENSURE_ARG_POINTER(aCurrentState); - if (mPersist) - { + if (mPersist) { mPersist->GetCurrentState(&mPersistCurrentState); } *aCurrentState = mPersistCurrentState; @@ -892,8 +879,7 @@ NS_IMETHODIMP nsWebBrowser::GetCurrentState(uint32_t *aCurrentState) NS_IMETHODIMP nsWebBrowser::GetResult(nsresult *aResult) { NS_ENSURE_ARG_POINTER(aResult); - if (mPersist) - { + if (mPersist) { mPersist->GetResult(&mPersistResult); } *aResult = mPersistResult; @@ -935,31 +921,23 @@ NS_IMETHODIMP nsWebBrowser::SavePrivacyAwareURI( nsIInputStream *aPostData, const char *aExtraHeaders, nsISupports *aFile, bool aIsPrivate) { - if (mPersist) - { + if (mPersist) { uint32_t currentState; mPersist->GetCurrentState(¤tState); - if (currentState == PERSIST_STATE_FINISHED) - { + if (currentState == PERSIST_STATE_FINISHED) { mPersist = nullptr; - } - else - { + } else { // You can't save again until the last save has completed return NS_ERROR_FAILURE; } } nsCOMPtr uri; - if (aURI) - { + if (aURI) { uri = aURI; - } - else - { + } else { nsresult rv = GetCurrentURI(getter_AddRefs(uri)); - if (NS_FAILED(rv)) - { + if (NS_FAILED(rv)) { return NS_ERROR_FAILURE; } } @@ -974,8 +952,7 @@ NS_IMETHODIMP nsWebBrowser::SavePrivacyAwareURI( rv = mPersist->SavePrivacyAwareURI(uri, aCacheKey, aReferrer, aReferrerPolicy, aPostData, aExtraHeaders, aFile, aIsPrivate); - if (NS_FAILED(rv)) - { + if (NS_FAILED(rv)) { mPersist = nullptr; } return rv; @@ -985,16 +962,12 @@ NS_IMETHODIMP nsWebBrowser::SavePrivacyAwareURI( NS_IMETHODIMP nsWebBrowser::SaveChannel( nsIChannel* aChannel, nsISupports *aFile) { - if (mPersist) - { + if (mPersist) { uint32_t currentState; mPersist->GetCurrentState(¤tState); - if (currentState == PERSIST_STATE_FINISHED) - { + if (currentState == PERSIST_STATE_FINISHED) { mPersist = nullptr; - } - else - { + } else { // You can't save again until the last save has completed return NS_ERROR_FAILURE; } @@ -1008,8 +981,7 @@ NS_IMETHODIMP nsWebBrowser::SaveChannel( mPersist->SetPersistFlags(mPersistFlags); mPersist->GetCurrentState(&mPersistCurrentState); rv = mPersist->SaveChannel(aChannel, aFile); - if (NS_FAILED(rv)) - { + if (NS_FAILED(rv)) { mPersist = nullptr; } return rv; @@ -1020,16 +992,12 @@ NS_IMETHODIMP nsWebBrowser::SaveDocument( nsIDOMDocument *aDocument, nsISupports *aFile, nsISupports *aDataPath, const char *aOutputContentType, uint32_t aEncodingFlags, uint32_t aWrapColumn) { - if (mPersist) - { + if (mPersist) { uint32_t currentState; mPersist->GetCurrentState(¤tState); - if (currentState == PERSIST_STATE_FINISHED) - { + if (currentState == PERSIST_STATE_FINISHED) { mPersist = nullptr; - } - else - { + } else { // You can't save again until the last save has completed return NS_ERROR_FAILURE; } @@ -1039,16 +1007,12 @@ NS_IMETHODIMP nsWebBrowser::SaveDocument( // attached to the web browser. nsCOMPtr doc; - if (aDocument) - { + if (aDocument) { doc = do_QueryInterface(aDocument); - } - else - { + } else { GetDocument(getter_AddRefs(doc)); } - if (!doc) - { + if (!doc) { return NS_ERROR_FAILURE; } @@ -1060,8 +1024,7 @@ NS_IMETHODIMP nsWebBrowser::SaveDocument( mPersist->SetPersistFlags(mPersistFlags); mPersist->GetCurrentState(&mPersistCurrentState); rv = mPersist->SaveDocument(doc, aFile, aDataPath, aOutputContentType, aEncodingFlags, aWrapColumn); - if (NS_FAILED(rv)) - { + if (NS_FAILED(rv)) { mPersist = nullptr; } return rv; @@ -1070,8 +1033,7 @@ NS_IMETHODIMP nsWebBrowser::SaveDocument( /* void cancelSave(); */ NS_IMETHODIMP nsWebBrowser::CancelSave() { - if (mPersist) - { + if (mPersist) { return mPersist->CancelSave(); } return NS_OK; @@ -1080,8 +1042,7 @@ NS_IMETHODIMP nsWebBrowser::CancelSave() /* void cancel(nsresult aReason); */ NS_IMETHODIMP nsWebBrowser::Cancel(nsresult aReason) { - if (mPersist) - { + if (mPersist) { return mPersist->Cancel(aReason); } return NS_OK; @@ -1120,11 +1081,10 @@ NS_IMETHODIMP nsWebBrowser::Create() NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr docShellParentWidget(mParentWidget); - if (!mParentWidget) // We need to create a widget - { + if (!mParentWidget) { // Create the widget - mInternalWidget = do_CreateInstance(kChildCID, &rv); - NS_ENSURE_SUCCESS(rv, rv); + mInternalWidget = do_CreateInstance(kChildCID, &rv); + NS_ENSURE_SUCCESS(rv, rv); docShellParentWidget = mInternalWidget; nsWidgetInitData widgetInit; @@ -1136,7 +1096,7 @@ NS_IMETHODIMP nsWebBrowser::Create() mInternalWidget->SetWidgetListener(this); mInternalWidget->Create(nullptr, mParentNativeWindow, bounds, nullptr, &widgetInit); - } + } nsCOMPtr docShell(do_CreateInstance("@mozilla.org/docshell;1", &rv)); NS_ENSURE_SUCCESS(rv, rv); @@ -1178,12 +1138,9 @@ NS_IMETHODIMP nsWebBrowser::Create() mInitInfo->cy), NS_ERROR_FAILURE); mDocShell->SetName(mInitInfo->name); - if (mContentType == typeChromeWrapper) - { + if (mContentType == typeChromeWrapper) { mDocShell->SetItemType(nsIDocShellTreeItem::typeChrome); - } - else - { + } else { mDocShell->SetItemType(nsIDocShellTreeItem::typeContent); } mDocShell->SetTreeOwner(mDocShellTreeOwner); @@ -1210,8 +1167,7 @@ NS_IMETHODIMP nsWebBrowser::Create() // updates nsCOMPtr domWindow; rv = GetContentDOMWindow(getter_AddRefs(domWindow)); - if (NS_SUCCEEDED(rv)) - { + if (NS_SUCCEEDED(rv)) { // this works because the implementation of nsISecureBrowserUI // (nsSecureBrowserUIImpl) gets a docShell from the domWindow, // and calls docShell->SetSecurityUI(this); @@ -1279,31 +1235,27 @@ NS_IMETHODIMP nsWebBrowser::GetSize(int32_t* aCX, int32_t* aCY) NS_IMETHODIMP nsWebBrowser::SetPositionAndSize(int32_t aX, int32_t aY, int32_t aCX, int32_t aCY, bool aRepaint) { - if (!mDocShell) - { + if (!mDocShell) { mInitInfo->x = aX; mInitInfo->y = aY; mInitInfo->cx = aCX; mInitInfo->cy = aCY; - } - else - { + } else { int32_t doc_x = aX; int32_t doc_y = aY; // If there is an internal widget we need to make the docShell coordinates // relative to the internal widget rather than the calling app's parent. // We also need to resize our widget then. - if (mInternalWidget) - { + if (mInternalWidget) { doc_x = doc_y = 0; NS_ENSURE_SUCCESS(mInternalWidget->Resize(aX, aY, aCX, aCY, aRepaint), NS_ERROR_FAILURE); - } + } // Now reposition/ resize the doc NS_ENSURE_SUCCESS(mDocShellAsWin->SetPositionAndSize(doc_x, doc_y, aCX, aCY, aRepaint), NS_ERROR_FAILURE); - } + } return NS_OK; } @@ -1311,8 +1263,7 @@ NS_IMETHODIMP nsWebBrowser::SetPositionAndSize(int32_t aX, int32_t aY, NS_IMETHODIMP nsWebBrowser::GetPositionAndSize(int32_t* aX, int32_t* aY, int32_t* aCX, int32_t* aCY) { - if (!mDocShell) - { + if (!mDocShell) { if (aX) *aX = mInitInfo->x; if (aY) @@ -1321,35 +1272,34 @@ NS_IMETHODIMP nsWebBrowser::GetPositionAndSize(int32_t* aX, int32_t* aY, *aCX = mInitInfo->cx; if (aCY) *aCY = mInitInfo->cy; - } - else - { - if (mInternalWidget) - { - nsIntRect bounds; - NS_ENSURE_SUCCESS(mInternalWidget->GetBounds(bounds), NS_ERROR_FAILURE); + } else if (mInternalWidget) { + nsIntRect bounds; + NS_ENSURE_SUCCESS(mInternalWidget->GetBounds(bounds), NS_ERROR_FAILURE); - if (aX) - *aX = bounds.x; - if (aY) - *aY = bounds.y; - if (aCX) - *aCX = bounds.width; - if (aCY) - *aCY = bounds.height; - return NS_OK; - } - else - return mDocShellAsWin->GetPositionAndSize(aX, aY, aCX, aCY); // Can directly return this as it is the - } + if (aX) + *aX = bounds.x; + if (aY) + *aY = bounds.y; + if (aCX) + *aCX = bounds.width; + if (aCY) + *aCY = bounds.height; + return NS_OK; + } else { + // Can directly return this as it is the + // same interface, thus same returns. + return mDocShellAsWin->GetPositionAndSize(aX, aY, aCX, aCY); + } return NS_OK; } NS_IMETHODIMP nsWebBrowser::Repaint(bool aForce) { NS_ENSURE_STATE(mDocShell); - return mDocShellAsWin->Repaint(aForce); // Can directly return this as it is the -} // same interface, thus same returns. + // Can directly return this as it is the + // same interface, thus same returns. + return mDocShellAsWin->Repaint(aForce); +} NS_IMETHODIMP nsWebBrowser::GetParentWidget(nsIWidget** aParentWidget) { @@ -1413,14 +1363,14 @@ NS_IMETHODIMP nsWebBrowser::GetVisibility(bool* visibility) NS_IMETHODIMP nsWebBrowser::SetVisibility(bool aVisibility) { - if (!mDocShell) + if (!mDocShell) { mInitInfo->visible = aVisibility; - else - { + } else { NS_ENSURE_SUCCESS(mDocShellAsWin->SetVisibility(aVisibility), NS_ERROR_FAILURE); - if (mInternalWidget) + if (mInternalWidget) { mInternalWidget->Show(aVisibility); } + } return NS_OK; } @@ -1541,8 +1491,7 @@ NS_IMETHODIMP nsWebBrowser::ScrollByPages(int32_t aNumPages) NS_IMETHODIMP nsWebBrowser::SetDocShell(nsIDocShell* aDocShell) { nsCOMPtr kungFuDeathGrip(mDocShell); - if (aDocShell) - { + if (aDocShell) { NS_ENSURE_TRUE(!mDocShell, NS_ERROR_FAILURE); nsCOMPtr req(do_QueryInterface(aDocShell)); @@ -1571,9 +1520,7 @@ NS_IMETHODIMP nsWebBrowser::SetDocShell(nsIDocShell* aDocShell) // default here (true) matches the default of the docshell, so this is // a no-op unless setIsActive(false) has been called on us. mDocShell->SetIsActive(mIsActive); - } - else - { + } else { if (mDocShellTreeOwner) mDocShellTreeOwner->RemoveFromWatcher(); // evil twin of Add in Create() if (mDocShellAsWin) diff --git a/embedding/browser/nsWebBrowser.h b/embedding/browser/nsWebBrowser.h index 78fdd5b96ae7..f027362204cf 100644 --- a/embedding/browser/nsWebBrowser.h +++ b/embedding/browser/nsWebBrowser.h @@ -60,8 +60,7 @@ class nsWebBrowserListenerState { public: bool Equals(nsIWeakReference *aListener, const nsIID& aID) { - if (mWeakPtr.get() == aListener && mID.Equals(aID)) return true; - return false; + return mWeakPtr.get() == aListener && mID.Equals(aID); } nsWeakPtr mWeakPtr; @@ -85,8 +84,8 @@ class nsWebBrowser MOZ_FINAL : public nsIWebBrowser, public nsIWebBrowserFocus, public nsIWebProgressListener, public nsIWebBrowserStream, - public nsIWidgetListener, - public nsSupportsWeakReference + public nsIWidgetListener, + public nsSupportsWeakReference { friend class nsDocShellTreeOwner; public: From c0fa6504f0672278a68cfa0ac2d376e8d0c15799 Mon Sep 17 00:00:00 2001 From: Andrew McCreight Date: Wed, 4 Feb 2015 15:15:12 -0800 Subject: [PATCH 42/74] Bug 1127430, part 2 - Fix indentation in nsWebBrowser. r=smaug --- embedding/browser/nsWebBrowser.cpp | 1736 ++++++++++++++-------------- embedding/browser/nsWebBrowser.h | 150 +-- 2 files changed, 952 insertions(+), 934 deletions(-) diff --git a/embedding/browser/nsWebBrowser.cpp b/embedding/browser/nsWebBrowser.cpp index 23b815535498..3b506d642927 100644 --- a/embedding/browser/nsWebBrowser.cpp +++ b/embedding/browser/nsWebBrowser.cpp @@ -1,4 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- 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/. */ @@ -65,48 +66,48 @@ static NS_DEFINE_CID(kChildCID, NS_CHILD_CID); //***************************************************************************** nsWebBrowser::nsWebBrowser() : - mInitInfo(new nsWebBrowserInitInfo()), - mContentType(typeContentWrapper), - mActivating(false), - mShouldEnableHistory(true), - mIsActive(true), - mParentNativeWindow(nullptr), - mProgressListener(nullptr), - mBackgroundColor(0), - mPersistCurrentState(nsIWebBrowserPersist::PERSIST_STATE_READY), - mPersistResult(NS_OK), - mPersistFlags(nsIWebBrowserPersist::PERSIST_FLAGS_NONE), - mParentWidget(nullptr) + mInitInfo(new nsWebBrowserInitInfo()), + mContentType(typeContentWrapper), + mActivating(false), + mShouldEnableHistory(true), + mIsActive(true), + mParentNativeWindow(nullptr), + mProgressListener(nullptr), + mBackgroundColor(0), + mPersistCurrentState(nsIWebBrowserPersist::PERSIST_STATE_READY), + mPersistResult(NS_OK), + mPersistFlags(nsIWebBrowserPersist::PERSIST_FLAGS_NONE), + mParentWidget(nullptr) { - mWWatch = do_GetService(NS_WINDOWWATCHER_CONTRACTID); - NS_ASSERTION(mWWatch, "failed to get WindowWatcher"); + mWWatch = do_GetService(NS_WINDOWWATCHER_CONTRACTID); + NS_ASSERTION(mWWatch, "failed to get WindowWatcher"); } nsWebBrowser::~nsWebBrowser() { - InternalDestroy(); + InternalDestroy(); } NS_IMETHODIMP nsWebBrowser::InternalDestroy() { - if (mInternalWidget) { - mInternalWidget->SetWidgetListener(nullptr); - mInternalWidget->Destroy(); - mInternalWidget = nullptr; // Force release here. - } + if (mInternalWidget) { + mInternalWidget->SetWidgetListener(nullptr); + mInternalWidget->Destroy(); + mInternalWidget = nullptr; // Force release here. + } - SetDocShell(nullptr); + SetDocShell(nullptr); - if (mDocShellTreeOwner) { - mDocShellTreeOwner->WebBrowser(nullptr); - mDocShellTreeOwner = nullptr; - } + if (mDocShellTreeOwner) { + mDocShellTreeOwner->WebBrowser(nullptr); + mDocShellTreeOwner = nullptr; + } - mInitInfo = nullptr; + mInitInfo = nullptr; - mListenerArray = nullptr; + mListenerArray = nullptr; - return NS_OK; + return NS_OK; } @@ -118,21 +119,21 @@ NS_IMPL_ADDREF(nsWebBrowser) NS_IMPL_RELEASE(nsWebBrowser) NS_INTERFACE_MAP_BEGIN(nsWebBrowser) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebBrowser) - NS_INTERFACE_MAP_ENTRY(nsIWebBrowser) - NS_INTERFACE_MAP_ENTRY(nsIWebNavigation) - NS_INTERFACE_MAP_ENTRY(nsIBaseWindow) - NS_INTERFACE_MAP_ENTRY(nsIScrollable) - NS_INTERFACE_MAP_ENTRY(nsITextScroll) - NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeItem) - NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor) - NS_INTERFACE_MAP_ENTRY(nsIWebBrowserSetup) - NS_INTERFACE_MAP_ENTRY(nsIWebBrowserPersist) - NS_INTERFACE_MAP_ENTRY(nsICancelable) - NS_INTERFACE_MAP_ENTRY(nsIWebBrowserFocus) - NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener) - NS_INTERFACE_MAP_ENTRY(nsIWebBrowserStream) - NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebBrowser) + NS_INTERFACE_MAP_ENTRY(nsIWebBrowser) + NS_INTERFACE_MAP_ENTRY(nsIWebNavigation) + NS_INTERFACE_MAP_ENTRY(nsIBaseWindow) + NS_INTERFACE_MAP_ENTRY(nsIScrollable) + NS_INTERFACE_MAP_ENTRY(nsITextScroll) + NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeItem) + NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor) + NS_INTERFACE_MAP_ENTRY(nsIWebBrowserSetup) + NS_INTERFACE_MAP_ENTRY(nsIWebBrowserPersist) + NS_INTERFACE_MAP_ENTRY(nsICancelable) + NS_INTERFACE_MAP_ENTRY(nsIWebBrowserFocus) + NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener) + NS_INTERFACE_MAP_ENTRY(nsIWebBrowserStream) + NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) NS_INTERFACE_MAP_END ///***************************************************************************** @@ -141,33 +142,33 @@ NS_INTERFACE_MAP_END NS_IMETHODIMP nsWebBrowser::GetInterface(const nsIID& aIID, void** aSink) { - NS_ENSURE_ARG_POINTER(aSink); + NS_ENSURE_ARG_POINTER(aSink); - if (NS_SUCCEEDED(QueryInterface(aIID, aSink))) { - return NS_OK; - } + if (NS_SUCCEEDED(QueryInterface(aIID, aSink))) { + return NS_OK; + } - if (mDocShell) { + if (mDocShell) { #ifdef NS_PRINTING - if (aIID.Equals(NS_GET_IID(nsIWebBrowserPrint))) { - nsCOMPtr viewer; - mDocShell->GetContentViewer(getter_AddRefs(viewer)); - if (!viewer) { - return NS_NOINTERFACE; - } + if (aIID.Equals(NS_GET_IID(nsIWebBrowserPrint))) { + nsCOMPtr viewer; + mDocShell->GetContentViewer(getter_AddRefs(viewer)); + if (!viewer) { + return NS_NOINTERFACE; + } - nsCOMPtr webBrowserPrint(do_QueryInterface(viewer)); - nsIWebBrowserPrint* print = (nsIWebBrowserPrint*)webBrowserPrint.get(); - NS_ASSERTION(print, "This MUST support this interface!"); - NS_ADDREF(print); - *aSink = print; - return NS_OK; - } + nsCOMPtr webBrowserPrint(do_QueryInterface(viewer)); + nsIWebBrowserPrint* print = (nsIWebBrowserPrint*)webBrowserPrint.get(); + NS_ASSERTION(print, "This MUST support this interface!"); + NS_ADDREF(print); + *aSink = print; + return NS_OK; + } #endif - return mDocShellAsReq->GetInterface(aIID, aSink); - } + return mDocShellAsReq->GetInterface(aIID, aSink); + } - return NS_NOINTERFACE; + return NS_NOINTERFACE; } //***************************************************************************** @@ -178,164 +179,160 @@ NS_IMETHODIMP nsWebBrowser::GetInterface(const nsIID& aIID, void** aSink) // - nsIWebProgressListener NS_IMETHODIMP nsWebBrowser::AddWebBrowserListener(nsIWeakReference *aListener, const nsIID& aIID) { - NS_ENSURE_ARG_POINTER(aListener); + NS_ENSURE_ARG_POINTER(aListener); - nsresult rv = NS_OK; - if (!mWebProgress) { - // The window hasn't been created yet, so queue up the listener. They'll be - // registered when the window gets created. - if (!mListenerArray) { - mListenerArray = new nsTArray(); - } - - nsWebBrowserListenerState* state = mListenerArray->AppendElement(); - state->mWeakPtr = aListener; - state->mID = aIID; - } else { - nsCOMPtr supports(do_QueryReferent(aListener)); - if (!supports) return NS_ERROR_INVALID_ARG; - rv = BindListener(supports, aIID); + nsresult rv = NS_OK; + if (!mWebProgress) { + // The window hasn't been created yet, so queue up the listener. They'll be + // registered when the window gets created. + if (!mListenerArray) { + mListenerArray = new nsTArray(); } - return rv; + nsWebBrowserListenerState* state = mListenerArray->AppendElement(); + state->mWeakPtr = aListener; + state->mID = aIID; + } else { + nsCOMPtr supports(do_QueryReferent(aListener)); + if (!supports) return NS_ERROR_INVALID_ARG; + rv = BindListener(supports, aIID); + } + + return rv; } NS_IMETHODIMP nsWebBrowser::BindListener(nsISupports *aListener, const nsIID& aIID) { - NS_ENSURE_ARG_POINTER(aListener); - NS_ASSERTION(mWebProgress, "this should only be called after we've retrieved a progress iface"); - nsresult rv = NS_OK; + NS_ENSURE_ARG_POINTER(aListener); + NS_ASSERTION(mWebProgress, "this should only be called after we've retrieved a progress iface"); + nsresult rv = NS_OK; - // register this listener for the specified interface id - if (aIID.Equals(NS_GET_IID(nsIWebProgressListener))) { - nsCOMPtr listener = do_QueryInterface(aListener, &rv); - if (NS_FAILED(rv)) return rv; - NS_ENSURE_STATE(mWebProgress); - rv = mWebProgress->AddProgressListener(listener, nsIWebProgress::NOTIFY_ALL); - } - else if (aIID.Equals(NS_GET_IID(nsISHistoryListener))) { - nsCOMPtr shistory(do_GetInterface(mDocShell, &rv)); - if (NS_FAILED(rv)) return rv; - nsCOMPtr listener(do_QueryInterface(aListener, &rv)); - if (NS_FAILED(rv)) return rv; - rv = shistory->AddSHistoryListener(listener); - } - return rv; + // register this listener for the specified interface id + if (aIID.Equals(NS_GET_IID(nsIWebProgressListener))) { + nsCOMPtr listener = do_QueryInterface(aListener, &rv); + if (NS_FAILED(rv)) return rv; + NS_ENSURE_STATE(mWebProgress); + rv = mWebProgress->AddProgressListener(listener, nsIWebProgress::NOTIFY_ALL); + } else if (aIID.Equals(NS_GET_IID(nsISHistoryListener))) { + nsCOMPtr shistory(do_GetInterface(mDocShell, &rv)); + if (NS_FAILED(rv)) return rv; + nsCOMPtr listener(do_QueryInterface(aListener, &rv)); + if (NS_FAILED(rv)) return rv; + rv = shistory->AddSHistoryListener(listener); + } + return rv; } NS_IMETHODIMP nsWebBrowser::RemoveWebBrowserListener(nsIWeakReference *aListener, const nsIID& aIID) { - NS_ENSURE_ARG_POINTER(aListener); + NS_ENSURE_ARG_POINTER(aListener); - nsresult rv = NS_OK; - if (!mWebProgress) { - // if there's no-one to register the listener w/, and we don't have a queue going, - // the the called is calling Remove before an Add which doesn't make sense. - if (!mListenerArray) return NS_ERROR_FAILURE; + nsresult rv = NS_OK; + if (!mWebProgress) { + // if there's no-one to register the listener w/, and we don't have a queue going, + // the the called is calling Remove before an Add which doesn't make sense. + if (!mListenerArray) return NS_ERROR_FAILURE; - // iterate the array and remove the queued listener - int32_t count = mListenerArray->Length(); - while (count > 0) { - if (mListenerArray->ElementAt(count).Equals(aListener, aIID)) { - mListenerArray->RemoveElementAt(count); - break; - } - count--; - } - - // if we've emptied the array, get rid of it. - if (0 >= mListenerArray->Length()) { - mListenerArray = nullptr; - } - - } else { - nsCOMPtr supports(do_QueryReferent(aListener)); - if (!supports) return NS_ERROR_INVALID_ARG; - rv = UnBindListener(supports, aIID); + // iterate the array and remove the queued listener + int32_t count = mListenerArray->Length(); + while (count > 0) { + if (mListenerArray->ElementAt(count).Equals(aListener, aIID)) { + mListenerArray->RemoveElementAt(count); + break; + } + count--; } - return rv; + // if we've emptied the array, get rid of it. + if (0 >= mListenerArray->Length()) { + mListenerArray = nullptr; + } + + } else { + nsCOMPtr supports(do_QueryReferent(aListener)); + if (!supports) return NS_ERROR_INVALID_ARG; + rv = UnBindListener(supports, aIID); + } + + return rv; } NS_IMETHODIMP nsWebBrowser::UnBindListener(nsISupports *aListener, const nsIID& aIID) { - NS_ENSURE_ARG_POINTER(aListener); - NS_ASSERTION(mWebProgress, "this should only be called after we've retrieved a progress iface"); - nsresult rv = NS_OK; + NS_ENSURE_ARG_POINTER(aListener); + NS_ASSERTION(mWebProgress, "this should only be called after we've retrieved a progress iface"); + nsresult rv = NS_OK; - // remove the listener for the specified interface id - if (aIID.Equals(NS_GET_IID(nsIWebProgressListener))) { - nsCOMPtr listener = do_QueryInterface(aListener, &rv); - if (NS_FAILED(rv)) return rv; - NS_ENSURE_STATE(mWebProgress); - rv = mWebProgress->RemoveProgressListener(listener); - } - else if (aIID.Equals(NS_GET_IID(nsISHistoryListener))) { - nsCOMPtr shistory(do_GetInterface(mDocShell, &rv)); - if (NS_FAILED(rv)) return rv; - nsCOMPtr listener(do_QueryInterface(aListener, &rv)); - if (NS_FAILED(rv)) return rv; - rv = shistory->RemoveSHistoryListener(listener); - } - return rv; + // remove the listener for the specified interface id + if (aIID.Equals(NS_GET_IID(nsIWebProgressListener))) { + nsCOMPtr listener = do_QueryInterface(aListener, &rv); + if (NS_FAILED(rv)) return rv; + NS_ENSURE_STATE(mWebProgress); + rv = mWebProgress->RemoveProgressListener(listener); + } else if (aIID.Equals(NS_GET_IID(nsISHistoryListener))) { + nsCOMPtr shistory(do_GetInterface(mDocShell, &rv)); + if (NS_FAILED(rv)) return rv; + nsCOMPtr listener(do_QueryInterface(aListener, &rv)); + if (NS_FAILED(rv)) return rv; + rv = shistory->RemoveSHistoryListener(listener); + } + return rv; } NS_IMETHODIMP nsWebBrowser::EnableGlobalHistory(bool aEnable) { - NS_ENSURE_STATE(mDocShell); + NS_ENSURE_STATE(mDocShell); - return mDocShell->SetUseGlobalHistory(aEnable); + return mDocShell->SetUseGlobalHistory(aEnable); } NS_IMETHODIMP nsWebBrowser::GetContainerWindow(nsIWebBrowserChrome** aTopWindow) { - NS_ENSURE_ARG_POINTER(aTopWindow); + NS_ENSURE_ARG_POINTER(aTopWindow); - nsCOMPtr top; - if (mDocShellTreeOwner) { - top = mDocShellTreeOwner->GetWebBrowserChrome(); - } + nsCOMPtr top; + if (mDocShellTreeOwner) { + top = mDocShellTreeOwner->GetWebBrowserChrome(); + } - top.forget(aTopWindow); + top.forget(aTopWindow); - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsWebBrowser::SetContainerWindow(nsIWebBrowserChrome* aTopWindow) { - NS_ENSURE_SUCCESS(EnsureDocShellTreeOwner(), NS_ERROR_FAILURE); - return mDocShellTreeOwner->SetWebBrowserChrome(aTopWindow); + NS_ENSURE_SUCCESS(EnsureDocShellTreeOwner(), NS_ERROR_FAILURE); + return mDocShellTreeOwner->SetWebBrowserChrome(aTopWindow); } -NS_IMETHODIMP nsWebBrowser::GetParentURIContentListener(nsIURIContentListener** - aParentContentListener) +NS_IMETHODIMP nsWebBrowser::GetParentURIContentListener(nsIURIContentListener** aParentContentListener) { - NS_ENSURE_ARG_POINTER(aParentContentListener); - *aParentContentListener = nullptr; + NS_ENSURE_ARG_POINTER(aParentContentListener); + *aParentContentListener = nullptr; - // get the interface from the docshell - nsCOMPtr listener(do_GetInterface(mDocShell)); + // get the interface from the docshell + nsCOMPtr listener(do_GetInterface(mDocShell)); - if (listener) - return listener->GetParentContentListener(aParentContentListener); - return NS_OK; + if (listener) + return listener->GetParentContentListener(aParentContentListener); + return NS_OK; } -NS_IMETHODIMP nsWebBrowser::SetParentURIContentListener(nsIURIContentListener* - aParentContentListener) +NS_IMETHODIMP nsWebBrowser::SetParentURIContentListener(nsIURIContentListener* aParentContentListener) { - // get the interface from the docshell - nsCOMPtr listener(do_GetInterface(mDocShell)); + // get the interface from the docshell + nsCOMPtr listener(do_GetInterface(mDocShell)); - if (listener) - return listener->SetParentContentListener(aParentContentListener); - return NS_ERROR_FAILURE; + if (listener) + return listener->SetParentContentListener(aParentContentListener); + return NS_ERROR_FAILURE; } NS_IMETHODIMP nsWebBrowser::GetContentDOMWindow(nsIDOMWindow **_retval) { - NS_ENSURE_STATE(mDocShell); - nsCOMPtr retval = mDocShell->GetWindow(); - retval.forget(_retval); - return *_retval ? NS_OK : NS_ERROR_FAILURE; + NS_ENSURE_STATE(mDocShell); + nsCOMPtr retval = mDocShell->GetWindow(); + retval.forget(_retval); + return *_retval ? NS_OK : NS_ERROR_FAILURE; } NS_IMETHODIMP nsWebBrowser::GetIsActive(bool *rv) @@ -361,121 +358,120 @@ NS_IMETHODIMP nsWebBrowser::SetIsActive(bool aIsActive) NS_IMETHODIMP nsWebBrowser::GetName(nsAString& aName) { - if (mDocShell) - mDocShell->GetName(aName); - else - aName = mInitInfo->name; + if (mDocShell) + mDocShell->GetName(aName); + else + aName = mInitInfo->name; - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsWebBrowser::SetName(const nsAString& aName) { - if (mDocShell) { - return mDocShell->SetName(aName); - } else { - mInitInfo->name = aName; - } + if (mDocShell) { + return mDocShell->SetName(aName); + } else { + mInitInfo->name = aName; + } - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsWebBrowser::NameEquals(const char16_t *aName, bool *_retval) { - NS_ENSURE_ARG_POINTER(aName); - NS_ENSURE_ARG_POINTER(_retval); - if (mDocShell) { - return mDocShell->NameEquals(aName, _retval); - } else { - *_retval = mInitInfo->name.Equals(aName); - } + NS_ENSURE_ARG_POINTER(aName); + NS_ENSURE_ARG_POINTER(_retval); + if (mDocShell) { + return mDocShell->NameEquals(aName, _retval); + } else { + *_retval = mInitInfo->name.Equals(aName); + } - return NS_OK; + return NS_OK; } /* virtual */ int32_t nsWebBrowser::ItemType() { - return mContentType; + return mContentType; } NS_IMETHODIMP nsWebBrowser::GetItemType(int32_t* aItemType) { - NS_ENSURE_ARG_POINTER(aItemType); + NS_ENSURE_ARG_POINTER(aItemType); - *aItemType = ItemType(); - return NS_OK; + *aItemType = ItemType(); + return NS_OK; } NS_IMETHODIMP nsWebBrowser::SetItemType(int32_t aItemType) { - NS_ENSURE_TRUE((aItemType == typeContentWrapper || aItemType == typeChromeWrapper), NS_ERROR_FAILURE); - mContentType = aItemType; - if (mDocShell) { - mDocShell->SetItemType(mContentType == typeChromeWrapper - ? static_cast(typeChrome) - : static_cast(typeContent)); - } + NS_ENSURE_TRUE((aItemType == typeContentWrapper || aItemType == typeChromeWrapper), NS_ERROR_FAILURE); + mContentType = aItemType; + if (mDocShell) { + mDocShell->SetItemType(mContentType == typeChromeWrapper + ? static_cast(typeChrome) + : static_cast(typeContent)); + } - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsWebBrowser::GetParent(nsIDocShellTreeItem** aParent) { - *aParent = nullptr; - return NS_OK; + *aParent = nullptr; + return NS_OK; } NS_IMETHODIMP nsWebBrowser::GetSameTypeParent(nsIDocShellTreeItem** aParent) { - *aParent = nullptr; + *aParent = nullptr; - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsWebBrowser::GetRootTreeItem(nsIDocShellTreeItem** aRootTreeItem) { - NS_ENSURE_ARG_POINTER(aRootTreeItem); - *aRootTreeItem = static_cast(this); + NS_ENSURE_ARG_POINTER(aRootTreeItem); + *aRootTreeItem = static_cast(this); - nsCOMPtr parent; - NS_ENSURE_SUCCESS(GetParent(getter_AddRefs(parent)), NS_ERROR_FAILURE); - while(parent) - { - *aRootTreeItem = parent; - NS_ENSURE_SUCCESS((*aRootTreeItem)->GetParent(getter_AddRefs(parent)), NS_ERROR_FAILURE); - } - NS_ADDREF(*aRootTreeItem); - return NS_OK; + nsCOMPtr parent; + NS_ENSURE_SUCCESS(GetParent(getter_AddRefs(parent)), NS_ERROR_FAILURE); + while(parent) { + *aRootTreeItem = parent; + NS_ENSURE_SUCCESS((*aRootTreeItem)->GetParent(getter_AddRefs(parent)), NS_ERROR_FAILURE); + } + NS_ADDREF(*aRootTreeItem); + return NS_OK; } NS_IMETHODIMP nsWebBrowser::GetSameTypeRootTreeItem(nsIDocShellTreeItem** aRootTreeItem) { - NS_ENSURE_ARG_POINTER(aRootTreeItem); - *aRootTreeItem = static_cast(this); + NS_ENSURE_ARG_POINTER(aRootTreeItem); + *aRootTreeItem = static_cast(this); - nsCOMPtr parent; - NS_ENSURE_SUCCESS(GetSameTypeParent(getter_AddRefs(parent)), NS_ERROR_FAILURE); - while(parent) - { - *aRootTreeItem = parent; - NS_ENSURE_SUCCESS((*aRootTreeItem)->GetSameTypeParent(getter_AddRefs(parent)), - NS_ERROR_FAILURE); - } - NS_ADDREF(*aRootTreeItem); - return NS_OK; + nsCOMPtr parent; + NS_ENSURE_SUCCESS(GetSameTypeParent(getter_AddRefs(parent)), NS_ERROR_FAILURE); + while(parent) { + *aRootTreeItem = parent; + NS_ENSURE_SUCCESS((*aRootTreeItem)->GetSameTypeParent(getter_AddRefs(parent)), + NS_ERROR_FAILURE); + } + NS_ADDREF(*aRootTreeItem); + return NS_OK; } NS_IMETHODIMP nsWebBrowser::FindItemWithName(const char16_t *aName, - nsISupports* aRequestor, nsIDocShellTreeItem* aOriginalRequestor, - nsIDocShellTreeItem **_retval) + nsISupports* aRequestor, + nsIDocShellTreeItem* aOriginalRequestor, + nsIDocShellTreeItem **_retval) { - NS_ENSURE_STATE(mDocShell); - NS_ASSERTION(mDocShellTreeOwner, "This should always be set when in this situation"); + NS_ENSURE_STATE(mDocShell); + NS_ASSERTION(mDocShellTreeOwner, "This should always be set when in this situation"); - return mDocShell->FindItemWithName(aName, - static_cast(mDocShellTreeOwner), - aOriginalRequestor, _retval); + return mDocShell->FindItemWithName(aName, + static_cast(mDocShellTreeOwner), + aOriginalRequestor, _retval); } nsIDocument* @@ -492,23 +488,23 @@ nsWebBrowser::GetWindow() NS_IMETHODIMP nsWebBrowser::GetTreeOwner(nsIDocShellTreeOwner** aTreeOwner) { - NS_ENSURE_ARG_POINTER(aTreeOwner); - *aTreeOwner = nullptr; - if (mDocShellTreeOwner) { - if (mDocShellTreeOwner->mTreeOwner) { - *aTreeOwner = mDocShellTreeOwner->mTreeOwner; - } else { - *aTreeOwner = mDocShellTreeOwner; - } + NS_ENSURE_ARG_POINTER(aTreeOwner); + *aTreeOwner = nullptr; + if (mDocShellTreeOwner) { + if (mDocShellTreeOwner->mTreeOwner) { + *aTreeOwner = mDocShellTreeOwner->mTreeOwner; + } else { + *aTreeOwner = mDocShellTreeOwner; } - NS_IF_ADDREF(*aTreeOwner); - return NS_OK; + } + NS_IF_ADDREF(*aTreeOwner); + return NS_OK; } NS_IMETHODIMP nsWebBrowser::SetTreeOwner(nsIDocShellTreeOwner* aTreeOwner) { - NS_ENSURE_SUCCESS(EnsureDocShellTreeOwner(), NS_ERROR_FAILURE); - return mDocShellTreeOwner->SetTreeOwner(aTreeOwner); + NS_ENSURE_SUCCESS(EnsureDocShellTreeOwner(), NS_ERROR_FAILURE); + return mDocShellTreeOwner->SetTreeOwner(aTreeOwner); } //***************************************************************************** @@ -517,38 +513,37 @@ NS_IMETHODIMP nsWebBrowser::SetTreeOwner(nsIDocShellTreeOwner* aTreeOwner) NS_IMETHODIMP nsWebBrowser::GetChildCount(int32_t * aChildCount) { - NS_ENSURE_ARG_POINTER(aChildCount); - *aChildCount = 0; - return NS_OK; + NS_ENSURE_ARG_POINTER(aChildCount); + *aChildCount = 0; + return NS_OK; } NS_IMETHODIMP nsWebBrowser::AddChild(nsIDocShellTreeItem * aChild) { - return NS_ERROR_UNEXPECTED; + return NS_ERROR_UNEXPECTED; } NS_IMETHODIMP nsWebBrowser::RemoveChild(nsIDocShellTreeItem * aChild) { - return NS_ERROR_UNEXPECTED; + return NS_ERROR_UNEXPECTED; } NS_IMETHODIMP nsWebBrowser::GetChildAt(int32_t aIndex, nsIDocShellTreeItem ** aChild) { - return NS_ERROR_UNEXPECTED; + return NS_ERROR_UNEXPECTED; } -NS_IMETHODIMP nsWebBrowser::FindChildWithName( - const char16_t * aName, - bool aRecurse, bool aSameType, - nsIDocShellTreeItem * aRequestor, - nsIDocShellTreeItem * aOriginalRequestor, - nsIDocShellTreeItem ** _retval) +NS_IMETHODIMP nsWebBrowser::FindChildWithName(const char16_t * aName, + bool aRecurse, bool aSameType, + nsIDocShellTreeItem * aRequestor, + nsIDocShellTreeItem * aOriginalRequestor, + nsIDocShellTreeItem ** _retval) { - NS_ENSURE_ARG_POINTER(_retval); + NS_ENSURE_ARG_POINTER(_retval); - *_retval = nullptr; - return NS_OK; + *_retval = nullptr; + return NS_OK; } //***************************************************************************** @@ -557,30 +552,30 @@ NS_IMETHODIMP nsWebBrowser::FindChildWithName( NS_IMETHODIMP nsWebBrowser::GetCanGoBack(bool* aCanGoBack) { - NS_ENSURE_STATE(mDocShell); + NS_ENSURE_STATE(mDocShell); - return mDocShellAsNav->GetCanGoBack(aCanGoBack); + return mDocShellAsNav->GetCanGoBack(aCanGoBack); } NS_IMETHODIMP nsWebBrowser::GetCanGoForward(bool* aCanGoForward) { - NS_ENSURE_STATE(mDocShell); + NS_ENSURE_STATE(mDocShell); - return mDocShellAsNav->GetCanGoForward(aCanGoForward); + return mDocShellAsNav->GetCanGoForward(aCanGoForward); } NS_IMETHODIMP nsWebBrowser::GoBack() { - NS_ENSURE_STATE(mDocShell); + NS_ENSURE_STATE(mDocShell); - return mDocShellAsNav->GoBack(); + return mDocShellAsNav->GoBack(); } NS_IMETHODIMP nsWebBrowser::GoForward() { - NS_ENSURE_STATE(mDocShell); + NS_ENSURE_STATE(mDocShell); - return mDocShellAsNav->GoForward(); + return mDocShellAsNav->GoForward(); } NS_IMETHODIMP nsWebBrowser::LoadURIWithBase(const char16_t* aURI, @@ -590,14 +585,14 @@ NS_IMETHODIMP nsWebBrowser::LoadURIWithBase(const char16_t* aURI, nsIInputStream* aExtraHeaderStream, nsIURI* aBaseURI) { - NS_ENSURE_STATE(mDocShell); + NS_ENSURE_STATE(mDocShell); - return mDocShellAsNav->LoadURIWithBase(aURI, - aLoadFlags, - aReferringURI, - aPostDataStream, - aExtraHeaderStream, - aBaseURI); + return mDocShellAsNav->LoadURIWithBase(aURI, + aLoadFlags, + aReferringURI, + aPostDataStream, + aExtraHeaderStream, + aBaseURI); } NS_IMETHODIMP nsWebBrowser::LoadURI(const char16_t* aURI, @@ -606,79 +601,79 @@ NS_IMETHODIMP nsWebBrowser::LoadURI(const char16_t* aURI, nsIInputStream* aPostDataStream, nsIInputStream* aExtraHeaderStream) { - NS_ENSURE_STATE(mDocShell); + NS_ENSURE_STATE(mDocShell); - return mDocShellAsNav->LoadURI(aURI, - aLoadFlags, - aReferringURI, - aPostDataStream, - aExtraHeaderStream); + return mDocShellAsNav->LoadURI(aURI, + aLoadFlags, + aReferringURI, + aPostDataStream, + aExtraHeaderStream); } NS_IMETHODIMP nsWebBrowser::Reload(uint32_t aReloadFlags) { - NS_ENSURE_STATE(mDocShell); + NS_ENSURE_STATE(mDocShell); - return mDocShellAsNav->Reload(aReloadFlags); + return mDocShellAsNav->Reload(aReloadFlags); } NS_IMETHODIMP nsWebBrowser::GotoIndex(int32_t aIndex) { - NS_ENSURE_STATE(mDocShell); + NS_ENSURE_STATE(mDocShell); - return mDocShellAsNav->GotoIndex(aIndex); + return mDocShellAsNav->GotoIndex(aIndex); } NS_IMETHODIMP nsWebBrowser::Stop(uint32_t aStopFlags) { - NS_ENSURE_STATE(mDocShell); + NS_ENSURE_STATE(mDocShell); - return mDocShellAsNav->Stop(aStopFlags); + return mDocShellAsNav->Stop(aStopFlags); } NS_IMETHODIMP nsWebBrowser::GetCurrentURI(nsIURI** aURI) { - NS_ENSURE_STATE(mDocShell); + NS_ENSURE_STATE(mDocShell); - return mDocShellAsNav->GetCurrentURI(aURI); + return mDocShellAsNav->GetCurrentURI(aURI); } NS_IMETHODIMP nsWebBrowser::GetReferringURI(nsIURI** aURI) { - NS_ENSURE_STATE(mDocShell); + NS_ENSURE_STATE(mDocShell); - return mDocShellAsNav->GetReferringURI(aURI); + return mDocShellAsNav->GetReferringURI(aURI); } NS_IMETHODIMP nsWebBrowser::SetSessionHistory(nsISHistory* aSessionHistory) { - if (mDocShell) - return mDocShellAsNav->SetSessionHistory(aSessionHistory); - else - mInitInfo->sessionHistory = aSessionHistory; + if (mDocShell) + return mDocShellAsNav->SetSessionHistory(aSessionHistory); + else + mInitInfo->sessionHistory = aSessionHistory; - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsWebBrowser::GetSessionHistory(nsISHistory** aSessionHistory) { - NS_ENSURE_ARG_POINTER(aSessionHistory); - if (mDocShell) - return mDocShellAsNav->GetSessionHistory(aSessionHistory); - else - *aSessionHistory = mInitInfo->sessionHistory; + NS_ENSURE_ARG_POINTER(aSessionHistory); + if (mDocShell) + return mDocShellAsNav->GetSessionHistory(aSessionHistory); + else + *aSessionHistory = mInitInfo->sessionHistory; - NS_IF_ADDREF(*aSessionHistory); + NS_IF_ADDREF(*aSessionHistory); - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsWebBrowser::GetDocument(nsIDOMDocument** aDocument) { - NS_ENSURE_STATE(mDocShell); + NS_ENSURE_STATE(mDocShell); - return mDocShellAsNav->GetDocument(aDocument); + return mDocShellAsNav->GetDocument(aDocument); } @@ -689,93 +684,92 @@ NS_IMETHODIMP nsWebBrowser::GetDocument(nsIDOMDocument** aDocument) /* void setProperty (in unsigned long aId, in unsigned long aValue); */ NS_IMETHODIMP nsWebBrowser::SetProperty(uint32_t aId, uint32_t aValue) { - nsresult rv = NS_OK; + nsresult rv = NS_OK; - switch (aId) + switch (aId) { + case nsIWebBrowserSetup::SETUP_ALLOW_PLUGINS: { - case nsIWebBrowserSetup::SETUP_ALLOW_PLUGINS: - { - NS_ENSURE_STATE(mDocShell); - NS_ENSURE_TRUE((aValue == static_cast(true) || - aValue == static_cast(false)), - NS_ERROR_INVALID_ARG); - mDocShell->SetAllowPlugins(!!aValue); - } - break; - case nsIWebBrowserSetup::SETUP_ALLOW_JAVASCRIPT: - { - NS_ENSURE_STATE(mDocShell); - NS_ENSURE_TRUE((aValue == static_cast(true) || - aValue == static_cast(false)), - NS_ERROR_INVALID_ARG); - mDocShell->SetAllowJavascript(!!aValue); - } - break; - case nsIWebBrowserSetup::SETUP_ALLOW_META_REDIRECTS: - { - NS_ENSURE_STATE(mDocShell); - NS_ENSURE_TRUE((aValue == static_cast(true) || - aValue == static_cast(false)), - NS_ERROR_INVALID_ARG); - mDocShell->SetAllowMetaRedirects(!!aValue); - } - break; - case nsIWebBrowserSetup::SETUP_ALLOW_SUBFRAMES: - { - NS_ENSURE_STATE(mDocShell); - NS_ENSURE_TRUE((aValue == static_cast(true) || - aValue == static_cast(false)), - NS_ERROR_INVALID_ARG); - mDocShell->SetAllowSubframes(!!aValue); - } - break; - case nsIWebBrowserSetup::SETUP_ALLOW_IMAGES: - { - NS_ENSURE_STATE(mDocShell); - NS_ENSURE_TRUE((aValue == static_cast(true) || - aValue == static_cast(false)), - NS_ERROR_INVALID_ARG); - mDocShell->SetAllowImages(!!aValue); - } - break; - case nsIWebBrowserSetup::SETUP_ALLOW_DNS_PREFETCH: - { - NS_ENSURE_STATE(mDocShell); - NS_ENSURE_TRUE((aValue == static_cast(true) || - aValue == static_cast(false)), - NS_ERROR_INVALID_ARG); - mDocShell->SetAllowDNSPrefetch(!!aValue); - } - break; - case nsIWebBrowserSetup::SETUP_USE_GLOBAL_HISTORY: - { - NS_ENSURE_STATE(mDocShell); - NS_ENSURE_TRUE((aValue == static_cast(true) || - aValue == static_cast(false)), - NS_ERROR_INVALID_ARG); - rv = EnableGlobalHistory(!!aValue); - mShouldEnableHistory = aValue; - } - break; - case nsIWebBrowserSetup::SETUP_FOCUS_DOC_BEFORE_CONTENT: - { - // obsolete - } - break; - case nsIWebBrowserSetup::SETUP_IS_CHROME_WRAPPER: - { - NS_ENSURE_TRUE((aValue == static_cast(true) || - aValue == static_cast(false)), - NS_ERROR_INVALID_ARG); - SetItemType(aValue ? static_cast(typeChromeWrapper) - : static_cast(typeContentWrapper)); - } - break; - default: - rv = NS_ERROR_INVALID_ARG; - + NS_ENSURE_STATE(mDocShell); + NS_ENSURE_TRUE((aValue == static_cast(true) || + aValue == static_cast(false)), + NS_ERROR_INVALID_ARG); + mDocShell->SetAllowPlugins(!!aValue); + break; } - return rv; + case nsIWebBrowserSetup::SETUP_ALLOW_JAVASCRIPT: + { + NS_ENSURE_STATE(mDocShell); + NS_ENSURE_TRUE((aValue == static_cast(true) || + aValue == static_cast(false)), + NS_ERROR_INVALID_ARG); + mDocShell->SetAllowJavascript(!!aValue); + break; + } + case nsIWebBrowserSetup::SETUP_ALLOW_META_REDIRECTS: + { + NS_ENSURE_STATE(mDocShell); + NS_ENSURE_TRUE((aValue == static_cast(true) || + aValue == static_cast(false)), + NS_ERROR_INVALID_ARG); + mDocShell->SetAllowMetaRedirects(!!aValue); + break; + } + case nsIWebBrowserSetup::SETUP_ALLOW_SUBFRAMES: + { + NS_ENSURE_STATE(mDocShell); + NS_ENSURE_TRUE((aValue == static_cast(true) || + aValue == static_cast(false)), + NS_ERROR_INVALID_ARG); + mDocShell->SetAllowSubframes(!!aValue); + break; + } + case nsIWebBrowserSetup::SETUP_ALLOW_IMAGES: + { + NS_ENSURE_STATE(mDocShell); + NS_ENSURE_TRUE((aValue == static_cast(true) || + aValue == static_cast(false)), + NS_ERROR_INVALID_ARG); + mDocShell->SetAllowImages(!!aValue); + break; + } + case nsIWebBrowserSetup::SETUP_ALLOW_DNS_PREFETCH: + { + NS_ENSURE_STATE(mDocShell); + NS_ENSURE_TRUE((aValue == static_cast(true) || + aValue == static_cast(false)), + NS_ERROR_INVALID_ARG); + mDocShell->SetAllowDNSPrefetch(!!aValue); + break; + } + case nsIWebBrowserSetup::SETUP_USE_GLOBAL_HISTORY: + { + NS_ENSURE_STATE(mDocShell); + NS_ENSURE_TRUE((aValue == static_cast(true) || + aValue == static_cast(false)), + NS_ERROR_INVALID_ARG); + rv = EnableGlobalHistory(!!aValue); + mShouldEnableHistory = aValue; + break; + } + case nsIWebBrowserSetup::SETUP_FOCUS_DOC_BEFORE_CONTENT: + { + // obsolete + break; + } + case nsIWebBrowserSetup::SETUP_IS_CHROME_WRAPPER: + { + NS_ENSURE_TRUE((aValue == static_cast(true) || + aValue == static_cast(false)), + NS_ERROR_INVALID_ARG); + SetItemType(aValue ? static_cast(typeChromeWrapper) + : static_cast(typeContentWrapper)); + break; + } + default: + rv = NS_ERROR_INVALID_ARG; + + } + return rv; } @@ -784,57 +778,73 @@ NS_IMETHODIMP nsWebBrowser::SetProperty(uint32_t aId, uint32_t aValue) //***************************************************************************** /* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long aStateFlags, in nsresult aStatus); */ -NS_IMETHODIMP nsWebBrowser::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t aStateFlags, nsresult aStatus) +NS_IMETHODIMP nsWebBrowser::OnStateChange(nsIWebProgress *aWebProgress, + nsIRequest *aRequest, + uint32_t aStateFlags, + nsresult aStatus) { - if (mPersist) { - mPersist->GetCurrentState(&mPersistCurrentState); - } - if (aStateFlags & STATE_IS_NETWORK && aStateFlags & STATE_STOP) { - mPersist = nullptr; - } - if (mProgressListener) { - return mProgressListener->OnStateChange(aWebProgress, aRequest, aStateFlags, aStatus); - } - return NS_OK; + if (mPersist) { + mPersist->GetCurrentState(&mPersistCurrentState); + } + if (aStateFlags & STATE_IS_NETWORK && aStateFlags & STATE_STOP) { + mPersist = nullptr; + } + if (mProgressListener) { + return mProgressListener->OnStateChange(aWebProgress, aRequest, aStateFlags, aStatus); + } + return NS_OK; } /* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */ -NS_IMETHODIMP nsWebBrowser::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, int32_t aCurSelfProgress, int32_t aMaxSelfProgress, int32_t aCurTotalProgress, int32_t aMaxTotalProgress) +NS_IMETHODIMP nsWebBrowser::OnProgressChange(nsIWebProgress *aWebProgress, + nsIRequest *aRequest, + int32_t aCurSelfProgress, + int32_t aMaxSelfProgress, + int32_t aCurTotalProgress, + int32_t aMaxTotalProgress) { - if (mPersist) { - mPersist->GetCurrentState(&mPersistCurrentState); - } - if (mProgressListener) { - return mProgressListener->OnProgressChange(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress); - } - return NS_OK; + if (mPersist) { + mPersist->GetCurrentState(&mPersistCurrentState); + } + if (mProgressListener) { + return mProgressListener->OnProgressChange(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress); + } + return NS_OK; } /* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location, in unsigned long aFlags); */ -NS_IMETHODIMP nsWebBrowser::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location, uint32_t aFlags) +NS_IMETHODIMP nsWebBrowser::OnLocationChange(nsIWebProgress *aWebProgress, + nsIRequest *aRequest, + nsIURI *location, + uint32_t aFlags) { - if (mProgressListener) { - return mProgressListener->OnLocationChange(aWebProgress, aRequest, location, aFlags); - } - return NS_OK; + if (mProgressListener) { + return mProgressListener->OnLocationChange(aWebProgress, aRequest, location, aFlags); + } + return NS_OK; } /* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */ -NS_IMETHODIMP nsWebBrowser::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const char16_t *aMessage) +NS_IMETHODIMP nsWebBrowser::OnStatusChange(nsIWebProgress *aWebProgress, + nsIRequest *aRequest, + nsresult aStatus, + const char16_t *aMessage) { - if (mProgressListener) { - return mProgressListener->OnStatusChange(aWebProgress, aRequest, aStatus, aMessage); - } - return NS_OK; + if (mProgressListener) { + return mProgressListener->OnStatusChange(aWebProgress, aRequest, aStatus, aMessage); + } + return NS_OK; } /* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */ -NS_IMETHODIMP nsWebBrowser::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t state) +NS_IMETHODIMP nsWebBrowser::OnSecurityChange(nsIWebProgress *aWebProgress, + nsIRequest *aRequest, + uint32_t state) { - if (mProgressListener) { - return mProgressListener->OnSecurityChange(aWebProgress, aRequest, state); - } - return NS_OK; + if (mProgressListener) { + return mProgressListener->OnSecurityChange(aWebProgress, aRequest, state); + } + return NS_OK; } //***************************************************************************** @@ -844,213 +854,220 @@ NS_IMETHODIMP nsWebBrowser::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRe /* attribute unsigned long persistFlags; */ NS_IMETHODIMP nsWebBrowser::GetPersistFlags(uint32_t *aPersistFlags) { - NS_ENSURE_ARG_POINTER(aPersistFlags); - nsresult rv = NS_OK; - if (mPersist) { - rv = mPersist->GetPersistFlags(&mPersistFlags); - } - *aPersistFlags = mPersistFlags; - return rv; + NS_ENSURE_ARG_POINTER(aPersistFlags); + nsresult rv = NS_OK; + if (mPersist) { + rv = mPersist->GetPersistFlags(&mPersistFlags); + } + *aPersistFlags = mPersistFlags; + return rv; } + NS_IMETHODIMP nsWebBrowser::SetPersistFlags(uint32_t aPersistFlags) { - nsresult rv = NS_OK; - mPersistFlags = aPersistFlags; - if (mPersist) { - rv = mPersist->SetPersistFlags(mPersistFlags); - mPersist->GetPersistFlags(&mPersistFlags); - } - return rv; + nsresult rv = NS_OK; + mPersistFlags = aPersistFlags; + if (mPersist) { + rv = mPersist->SetPersistFlags(mPersistFlags); + mPersist->GetPersistFlags(&mPersistFlags); + } + return rv; } /* readonly attribute unsigned long currentState; */ NS_IMETHODIMP nsWebBrowser::GetCurrentState(uint32_t *aCurrentState) { - NS_ENSURE_ARG_POINTER(aCurrentState); - if (mPersist) { - mPersist->GetCurrentState(&mPersistCurrentState); - } - *aCurrentState = mPersistCurrentState; - return NS_OK; + NS_ENSURE_ARG_POINTER(aCurrentState); + if (mPersist) { + mPersist->GetCurrentState(&mPersistCurrentState); + } + *aCurrentState = mPersistCurrentState; + return NS_OK; } /* readonly attribute nsresult result; */ NS_IMETHODIMP nsWebBrowser::GetResult(nsresult *aResult) { - NS_ENSURE_ARG_POINTER(aResult); - if (mPersist) { - mPersist->GetResult(&mPersistResult); - } - *aResult = mPersistResult; - return NS_OK; + NS_ENSURE_ARG_POINTER(aResult); + if (mPersist) { + mPersist->GetResult(&mPersistResult); + } + *aResult = mPersistResult; + return NS_OK; } /* attribute nsIWebBrowserPersistProgress progressListener; */ NS_IMETHODIMP nsWebBrowser::GetProgressListener(nsIWebProgressListener * *aProgressListener) { - NS_ENSURE_ARG_POINTER(aProgressListener); - *aProgressListener = mProgressListener; - NS_IF_ADDREF(*aProgressListener); - return NS_OK; + NS_ENSURE_ARG_POINTER(aProgressListener); + *aProgressListener = mProgressListener; + NS_IF_ADDREF(*aProgressListener); + return NS_OK; } NS_IMETHODIMP nsWebBrowser::SetProgressListener(nsIWebProgressListener * aProgressListener) { - mProgressListener = aProgressListener; - return NS_OK; + mProgressListener = aProgressListener; + return NS_OK; } /* void saveURI (in nsIURI aURI, in nsIURI aReferrer, in unsigned long aReferrerPolicy in nsISupports aCacheKey, in nsIInputStream aPostData, in wstring aExtraHeaders, in nsISupports aFile, in nsILoadContext aPrivacyContext); */ -NS_IMETHODIMP nsWebBrowser::SaveURI( - nsIURI *aURI, nsISupports *aCacheKey, - nsIURI *aReferrer, uint32_t aReferrerPolicy, - nsIInputStream *aPostData, const char *aExtraHeaders, - nsISupports *aFile, nsILoadContext* aPrivacyContext) +NS_IMETHODIMP nsWebBrowser::SaveURI(nsIURI *aURI, + nsISupports *aCacheKey, + nsIURI *aReferrer, + uint32_t aReferrerPolicy, + nsIInputStream *aPostData, + const char *aExtraHeaders, + nsISupports *aFile, + nsILoadContext* aPrivacyContext) { - return SavePrivacyAwareURI(aURI, aCacheKey, aReferrer, aReferrerPolicy, - aPostData, aExtraHeaders, - aFile, aPrivacyContext && aPrivacyContext->UsePrivateBrowsing()); + return SavePrivacyAwareURI(aURI, aCacheKey, aReferrer, aReferrerPolicy, + aPostData, aExtraHeaders, + aFile, aPrivacyContext && aPrivacyContext->UsePrivateBrowsing()); } -NS_IMETHODIMP nsWebBrowser::SavePrivacyAwareURI( - nsIURI *aURI, nsISupports *aCacheKey, - nsIURI *aReferrer, uint32_t aReferrerPolicy, - nsIInputStream *aPostData, const char *aExtraHeaders, - nsISupports *aFile, bool aIsPrivate) +NS_IMETHODIMP nsWebBrowser::SavePrivacyAwareURI(nsIURI *aURI, + nsISupports *aCacheKey, + nsIURI *aReferrer, + uint32_t aReferrerPolicy, + nsIInputStream *aPostData, + const char *aExtraHeaders, + nsISupports *aFile, + bool aIsPrivate) { - if (mPersist) { - uint32_t currentState; - mPersist->GetCurrentState(¤tState); - if (currentState == PERSIST_STATE_FINISHED) { - mPersist = nullptr; - } else { - // You can't save again until the last save has completed - return NS_ERROR_FAILURE; - } - } - - nsCOMPtr uri; - if (aURI) { - uri = aURI; + if (mPersist) { + uint32_t currentState; + mPersist->GetCurrentState(¤tState); + if (currentState == PERSIST_STATE_FINISHED) { + mPersist = nullptr; } else { - nsresult rv = GetCurrentURI(getter_AddRefs(uri)); - if (NS_FAILED(rv)) { - return NS_ERROR_FAILURE; - } + // You can't save again until the last save has completed + return NS_ERROR_FAILURE; } + } - // Create a throwaway persistence object to do the work - nsresult rv; - mPersist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - mPersist->SetProgressListener(this); - mPersist->SetPersistFlags(mPersistFlags); - mPersist->GetCurrentState(&mPersistCurrentState); - - rv = mPersist->SavePrivacyAwareURI(uri, aCacheKey, aReferrer, aReferrerPolicy, - aPostData, aExtraHeaders, aFile, aIsPrivate); + nsCOMPtr uri; + if (aURI) { + uri = aURI; + } else { + nsresult rv = GetCurrentURI(getter_AddRefs(uri)); if (NS_FAILED(rv)) { - mPersist = nullptr; + return NS_ERROR_FAILURE; } - return rv; + } + + // Create a throwaway persistence object to do the work + nsresult rv; + mPersist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + mPersist->SetProgressListener(this); + mPersist->SetPersistFlags(mPersistFlags); + mPersist->GetCurrentState(&mPersistCurrentState); + + rv = mPersist->SavePrivacyAwareURI(uri, aCacheKey, aReferrer, aReferrerPolicy, + aPostData, aExtraHeaders, aFile, aIsPrivate); + if (NS_FAILED(rv)) { + mPersist = nullptr; + } + return rv; } /* void saveChannel (in nsIChannel aChannel, in nsISupports aFile); */ -NS_IMETHODIMP nsWebBrowser::SaveChannel( - nsIChannel* aChannel, nsISupports *aFile) +NS_IMETHODIMP nsWebBrowser::SaveChannel(nsIChannel* aChannel, nsISupports *aFile) { - if (mPersist) { - uint32_t currentState; - mPersist->GetCurrentState(¤tState); - if (currentState == PERSIST_STATE_FINISHED) { - mPersist = nullptr; - } else { - // You can't save again until the last save has completed - return NS_ERROR_FAILURE; - } + if (mPersist) { + uint32_t currentState; + mPersist->GetCurrentState(¤tState); + if (currentState == PERSIST_STATE_FINISHED) { + mPersist = nullptr; + } else { + // You can't save again until the last save has completed + return NS_ERROR_FAILURE; } + } - // Create a throwaway persistence object to do the work - nsresult rv; - mPersist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - mPersist->SetProgressListener(this); - mPersist->SetPersistFlags(mPersistFlags); - mPersist->GetCurrentState(&mPersistCurrentState); - rv = mPersist->SaveChannel(aChannel, aFile); - if (NS_FAILED(rv)) { - mPersist = nullptr; - } - return rv; + // Create a throwaway persistence object to do the work + nsresult rv; + mPersist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + mPersist->SetProgressListener(this); + mPersist->SetPersistFlags(mPersistFlags); + mPersist->GetCurrentState(&mPersistCurrentState); + rv = mPersist->SaveChannel(aChannel, aFile); + if (NS_FAILED(rv)) { + mPersist = nullptr; + } + return rv; } /* void saveDocument (in nsIDOMDocument document, in nsISupports aFile, in nsISupports aDataPath); */ -NS_IMETHODIMP nsWebBrowser::SaveDocument( - nsIDOMDocument *aDocument, nsISupports *aFile, nsISupports *aDataPath, - const char *aOutputContentType, uint32_t aEncodingFlags, uint32_t aWrapColumn) +NS_IMETHODIMP nsWebBrowser::SaveDocument(nsIDOMDocument *aDocument, + nsISupports *aFile, + nsISupports *aDataPath, + const char *aOutputContentType, + uint32_t aEncodingFlags, + uint32_t aWrapColumn) { - if (mPersist) { - uint32_t currentState; - mPersist->GetCurrentState(¤tState); - if (currentState == PERSIST_STATE_FINISHED) { - mPersist = nullptr; - } else { - // You can't save again until the last save has completed - return NS_ERROR_FAILURE; - } - } - - // Use the specified DOM document, or if none is specified, the one - // attached to the web browser. - - nsCOMPtr doc; - if (aDocument) { - doc = do_QueryInterface(aDocument); + if (mPersist) { + uint32_t currentState; + mPersist->GetCurrentState(¤tState); + if (currentState == PERSIST_STATE_FINISHED) { + mPersist = nullptr; } else { - GetDocument(getter_AddRefs(doc)); - } - if (!doc) { - return NS_ERROR_FAILURE; + // You can't save again until the last save has completed + return NS_ERROR_FAILURE; } + } - // Create a throwaway persistence object to do the work - nsresult rv; - mPersist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - mPersist->SetProgressListener(this); - mPersist->SetPersistFlags(mPersistFlags); - mPersist->GetCurrentState(&mPersistCurrentState); - rv = mPersist->SaveDocument(doc, aFile, aDataPath, aOutputContentType, aEncodingFlags, aWrapColumn); - if (NS_FAILED(rv)) { - mPersist = nullptr; - } - return rv; + // Use the specified DOM document, or if none is specified, the one + // attached to the web browser. + + nsCOMPtr doc; + if (aDocument) { + doc = do_QueryInterface(aDocument); + } else { + GetDocument(getter_AddRefs(doc)); + } + if (!doc) { + return NS_ERROR_FAILURE; + } + + // Create a throwaway persistence object to do the work + nsresult rv; + mPersist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + mPersist->SetProgressListener(this); + mPersist->SetPersistFlags(mPersistFlags); + mPersist->GetCurrentState(&mPersistCurrentState); + rv = mPersist->SaveDocument(doc, aFile, aDataPath, aOutputContentType, aEncodingFlags, aWrapColumn); + if (NS_FAILED(rv)) { + mPersist = nullptr; + } + return rv; } /* void cancelSave(); */ NS_IMETHODIMP nsWebBrowser::CancelSave() { - if (mPersist) { - return mPersist->CancelSave(); - } + if (mPersist) { + return mPersist->CancelSave(); + } return NS_OK; } /* void cancel(nsresult aReason); */ NS_IMETHODIMP nsWebBrowser::Cancel(nsresult aReason) { - if (mPersist) { - return mPersist->Cancel(aReason); - } - return NS_OK; + if (mPersist) { + return mPersist->Cancel(aReason); + } + return NS_OK; } - - //***************************************************************************** // nsWebBrowser::nsIBaseWindow //***************************************************************************** @@ -1058,142 +1075,142 @@ NS_IMETHODIMP nsWebBrowser::Cancel(nsresult aReason) NS_IMETHODIMP nsWebBrowser::InitWindow(nativeWindow aParentNativeWindow, nsIWidget* aParentWidget, int32_t aX, int32_t aY, int32_t aCX, int32_t aCY) { - NS_ENSURE_ARG(aParentNativeWindow || aParentWidget); - NS_ENSURE_STATE(!mDocShell || mInitInfo); + NS_ENSURE_ARG(aParentNativeWindow || aParentWidget); + NS_ENSURE_STATE(!mDocShell || mInitInfo); - if (aParentWidget) - NS_ENSURE_SUCCESS(SetParentWidget(aParentWidget), NS_ERROR_FAILURE); - else - NS_ENSURE_SUCCESS(SetParentNativeWindow(aParentNativeWindow), - NS_ERROR_FAILURE); + if (aParentWidget) + NS_ENSURE_SUCCESS(SetParentWidget(aParentWidget), NS_ERROR_FAILURE); + else + NS_ENSURE_SUCCESS(SetParentNativeWindow(aParentNativeWindow), + NS_ERROR_FAILURE); - NS_ENSURE_SUCCESS(SetPositionAndSize(aX, aY, aCX, aCY, false), - NS_ERROR_FAILURE); + NS_ENSURE_SUCCESS(SetPositionAndSize(aX, aY, aCX, aCY, false), + NS_ERROR_FAILURE); - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsWebBrowser::Create() { - NS_ENSURE_STATE(!mDocShell && (mParentNativeWindow || mParentWidget)); + NS_ENSURE_STATE(!mDocShell && (mParentNativeWindow || mParentWidget)); - nsresult rv = EnsureDocShellTreeOwner(); + nsresult rv = EnsureDocShellTreeOwner(); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr docShellParentWidget(mParentWidget); + if (!mParentWidget) { + // Create the widget + mInternalWidget = do_CreateInstance(kChildCID, &rv); NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr docShellParentWidget(mParentWidget); - if (!mParentWidget) { - // Create the widget - mInternalWidget = do_CreateInstance(kChildCID, &rv); - NS_ENSURE_SUCCESS(rv, rv); + docShellParentWidget = mInternalWidget; + nsWidgetInitData widgetInit; - docShellParentWidget = mInternalWidget; - nsWidgetInitData widgetInit; + widgetInit.clipChildren = true; - widgetInit.clipChildren = true; + widgetInit.mWindowType = eWindowType_child; + nsIntRect bounds(mInitInfo->x, mInitInfo->y, mInitInfo->cx, mInitInfo->cy); - widgetInit.mWindowType = eWindowType_child; - nsIntRect bounds(mInitInfo->x, mInitInfo->y, mInitInfo->cx, mInitInfo->cy); + mInternalWidget->SetWidgetListener(this); + mInternalWidget->Create(nullptr, mParentNativeWindow, bounds, nullptr, &widgetInit); + } - mInternalWidget->SetWidgetListener(this); - mInternalWidget->Create(nullptr, mParentNativeWindow, bounds, nullptr, &widgetInit); - } + nsCOMPtr docShell(do_CreateInstance("@mozilla.org/docshell;1", &rv)); + NS_ENSURE_SUCCESS(rv, rv); + rv = SetDocShell(docShell); + NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr docShell(do_CreateInstance("@mozilla.org/docshell;1", &rv)); - NS_ENSURE_SUCCESS(rv, rv); - rv = SetDocShell(docShell); - NS_ENSURE_SUCCESS(rv, rv); + // get the system default window background colour + LookAndFeel::GetColor(LookAndFeel::eColorID_WindowBackground, + &mBackgroundColor); - // get the system default window background colour - LookAndFeel::GetColor(LookAndFeel::eColorID_WindowBackground, - &mBackgroundColor); - - // the docshell has been set so we now have our listener registrars. - if (mListenerArray) { - // we had queued up some listeners, let's register them now. - uint32_t count = mListenerArray->Length(); - uint32_t i = 0; - NS_ASSERTION(count > 0, "array construction problem"); - while (i < count) { - nsWebBrowserListenerState& state = mListenerArray->ElementAt(i); - nsCOMPtr listener = do_QueryReferent(state.mWeakPtr); - NS_ASSERTION(listener, "bad listener"); - (void)BindListener(listener, state.mID); - i++; - } - mListenerArray = nullptr; - } - - // HACK ALERT - this registration registers the nsDocShellTreeOwner as a - // nsIWebBrowserListener so it can setup its MouseListener in one of the - // progress callbacks. If we can register the MouseListener another way, this - // registration can go away, and nsDocShellTreeOwner can stop implementing - // nsIWebProgressListener. - nsCOMPtr supports = nullptr; - (void)mDocShellTreeOwner->QueryInterface(NS_GET_IID(nsIWebProgressListener), - static_cast(getter_AddRefs(supports))); - (void)BindListener(supports, NS_GET_IID(nsIWebProgressListener)); - - NS_ENSURE_SUCCESS(mDocShellAsWin->InitWindow(nullptr, - docShellParentWidget, mInitInfo->x, mInitInfo->y, mInitInfo->cx, - mInitInfo->cy), NS_ERROR_FAILURE); - - mDocShell->SetName(mInitInfo->name); - if (mContentType == typeChromeWrapper) { - mDocShell->SetItemType(nsIDocShellTreeItem::typeChrome); - } else { - mDocShell->SetItemType(nsIDocShellTreeItem::typeContent); - } - mDocShell->SetTreeOwner(mDocShellTreeOwner); - - // If the webbrowser is a content docshell item then we won't hear any - // events from subframes. To solve that we install our own chrome event handler - // that always gets called (even for subframes) for any bubbling event. - - if (!mInitInfo->sessionHistory) { - mInitInfo->sessionHistory = do_CreateInstance(NS_SHISTORY_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); + // the docshell has been set so we now have our listener registrars. + if (mListenerArray) { + // we had queued up some listeners, let's register them now. + uint32_t count = mListenerArray->Length(); + uint32_t i = 0; + NS_ASSERTION(count > 0, "array construction problem"); + while (i < count) { + nsWebBrowserListenerState& state = mListenerArray->ElementAt(i); + nsCOMPtr listener = do_QueryReferent(state.mWeakPtr); + NS_ASSERTION(listener, "bad listener"); + (void)BindListener(listener, state.mID); + i++; } - mDocShellAsNav->SetSessionHistory(mInitInfo->sessionHistory); + mListenerArray = nullptr; + } - if (XRE_GetProcessType() == GeckoProcessType_Default) { - // Hook up global history. Do not fail if we can't - just warn. - rv = EnableGlobalHistory(mShouldEnableHistory); - NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "EnableGlobalHistory() failed"); - } + // HACK ALERT - this registration registers the nsDocShellTreeOwner as a + // nsIWebBrowserListener so it can setup its MouseListener in one of the + // progress callbacks. If we can register the MouseListener another way, this + // registration can go away, and nsDocShellTreeOwner can stop implementing + // nsIWebProgressListener. + nsCOMPtr supports = nullptr; + (void)mDocShellTreeOwner->QueryInterface(NS_GET_IID(nsIWebProgressListener), + static_cast(getter_AddRefs(supports))); + (void)BindListener(supports, NS_GET_IID(nsIWebProgressListener)); - NS_ENSURE_SUCCESS(mDocShellAsWin->Create(), NS_ERROR_FAILURE); + NS_ENSURE_SUCCESS(mDocShellAsWin->InitWindow(nullptr, + docShellParentWidget, mInitInfo->x, mInitInfo->y, mInitInfo->cx, + mInitInfo->cy), NS_ERROR_FAILURE); - // Hook into the OnSecurityChange() notification for lock/unlock icon - // updates - nsCOMPtr domWindow; - rv = GetContentDOMWindow(getter_AddRefs(domWindow)); - if (NS_SUCCEEDED(rv)) { - // this works because the implementation of nsISecureBrowserUI - // (nsSecureBrowserUIImpl) gets a docShell from the domWindow, - // and calls docShell->SetSecurityUI(this); - nsCOMPtr securityUI = - do_CreateInstance(NS_SECURE_BROWSER_UI_CONTRACTID, &rv); - if (NS_SUCCEEDED(rv)) - securityUI->Init(domWindow); - } + mDocShell->SetName(mInitInfo->name); + if (mContentType == typeChromeWrapper) { + mDocShell->SetItemType(nsIDocShellTreeItem::typeChrome); + } else { + mDocShell->SetItemType(nsIDocShellTreeItem::typeContent); + } + mDocShell->SetTreeOwner(mDocShellTreeOwner); - mDocShellTreeOwner->AddToWatcher(); // evil twin of Remove in SetDocShell(0) - mDocShellTreeOwner->AddChromeListeners(); + // If the webbrowser is a content docshell item then we won't hear any + // events from subframes. To solve that we install our own chrome event handler + // that always gets called (even for subframes) for any bubbling event. - mInitInfo = nullptr; + if (!mInitInfo->sessionHistory) { + mInitInfo->sessionHistory = do_CreateInstance(NS_SHISTORY_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + } + mDocShellAsNav->SetSessionHistory(mInitInfo->sessionHistory); - return NS_OK; + if (XRE_GetProcessType() == GeckoProcessType_Default) { + // Hook up global history. Do not fail if we can't - just warn. + rv = EnableGlobalHistory(mShouldEnableHistory); + NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "EnableGlobalHistory() failed"); + } + + NS_ENSURE_SUCCESS(mDocShellAsWin->Create(), NS_ERROR_FAILURE); + + // Hook into the OnSecurityChange() notification for lock/unlock icon + // updates + nsCOMPtr domWindow; + rv = GetContentDOMWindow(getter_AddRefs(domWindow)); + if (NS_SUCCEEDED(rv)) { + // this works because the implementation of nsISecureBrowserUI + // (nsSecureBrowserUIImpl) gets a docShell from the domWindow, + // and calls docShell->SetSecurityUI(this); + nsCOMPtr securityUI = + do_CreateInstance(NS_SECURE_BROWSER_UI_CONTRACTID, &rv); + if (NS_SUCCEEDED(rv)) + securityUI->Init(domWindow); + } + + mDocShellTreeOwner->AddToWatcher(); // evil twin of Remove in SetDocShell(0) + mDocShellTreeOwner->AddChromeListeners(); + + mInitInfo = nullptr; + + return NS_OK; } NS_IMETHODIMP nsWebBrowser::Destroy() { - InternalDestroy(); + InternalDestroy(); - if (!mInitInfo) { - mInitInfo = new nsWebBrowserInitInfo(); - } + if (!mInitInfo) { + mInitInfo = new nsWebBrowserInitInfo(); + } - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsWebBrowser::GetUnscaledDevicePixelsPerCSSPixel(double *aScale) @@ -1204,175 +1221,176 @@ NS_IMETHODIMP nsWebBrowser::GetUnscaledDevicePixelsPerCSSPixel(double *aScale) NS_IMETHODIMP nsWebBrowser::SetPosition(int32_t aX, int32_t aY) { - int32_t cx = 0; - int32_t cy = 0; + int32_t cx = 0; + int32_t cy = 0; - GetSize(&cx, &cy); + GetSize(&cx, &cy); - return SetPositionAndSize(aX, aY, cx, cy, false); + return SetPositionAndSize(aX, aY, cx, cy, false); } NS_IMETHODIMP nsWebBrowser::GetPosition(int32_t* aX, int32_t* aY) { - return GetPositionAndSize(aX, aY, nullptr, nullptr); + return GetPositionAndSize(aX, aY, nullptr, nullptr); } NS_IMETHODIMP nsWebBrowser::SetSize(int32_t aCX, int32_t aCY, bool aRepaint) { - int32_t x = 0; - int32_t y = 0; + int32_t x = 0; + int32_t y = 0; - GetPosition(&x, &y); + GetPosition(&x, &y); - return SetPositionAndSize(x, y, aCX, aCY, aRepaint); + return SetPositionAndSize(x, y, aCX, aCY, aRepaint); } NS_IMETHODIMP nsWebBrowser::GetSize(int32_t* aCX, int32_t* aCY) { - return GetPositionAndSize(nullptr, nullptr, aCX, aCY); + return GetPositionAndSize(nullptr, nullptr, aCX, aCY); } NS_IMETHODIMP nsWebBrowser::SetPositionAndSize(int32_t aX, int32_t aY, - int32_t aCX, int32_t aCY, bool aRepaint) + int32_t aCX, int32_t aCY, + bool aRepaint) { - if (!mDocShell) { - mInitInfo->x = aX; - mInitInfo->y = aY; - mInitInfo->cx = aCX; - mInitInfo->cy = aCY; - } else { - int32_t doc_x = aX; - int32_t doc_y = aY; + if (!mDocShell) { + mInitInfo->x = aX; + mInitInfo->y = aY; + mInitInfo->cx = aCX; + mInitInfo->cy = aCY; + } else { + int32_t doc_x = aX; + int32_t doc_y = aY; - // If there is an internal widget we need to make the docShell coordinates - // relative to the internal widget rather than the calling app's parent. - // We also need to resize our widget then. - if (mInternalWidget) { - doc_x = doc_y = 0; - NS_ENSURE_SUCCESS(mInternalWidget->Resize(aX, aY, aCX, aCY, aRepaint), - NS_ERROR_FAILURE); - } - // Now reposition/ resize the doc - NS_ENSURE_SUCCESS(mDocShellAsWin->SetPositionAndSize(doc_x, doc_y, aCX, aCY, - aRepaint), NS_ERROR_FAILURE); - } + // If there is an internal widget we need to make the docShell coordinates + // relative to the internal widget rather than the calling app's parent. + // We also need to resize our widget then. + if (mInternalWidget) { + doc_x = doc_y = 0; + NS_ENSURE_SUCCESS(mInternalWidget->Resize(aX, aY, aCX, aCY, aRepaint), + NS_ERROR_FAILURE); + } + // Now reposition/ resize the doc + NS_ENSURE_SUCCESS(mDocShellAsWin->SetPositionAndSize(doc_x, doc_y, aCX, aCY, + aRepaint), NS_ERROR_FAILURE); + } - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsWebBrowser::GetPositionAndSize(int32_t* aX, int32_t* aY, - int32_t* aCX, int32_t* aCY) + int32_t* aCX, int32_t* aCY) { - if (!mDocShell) { - if (aX) - *aX = mInitInfo->x; - if (aY) - *aY = mInitInfo->y; - if (aCX) - *aCX = mInitInfo->cx; - if (aCY) - *aCY = mInitInfo->cy; - } else if (mInternalWidget) { - nsIntRect bounds; - NS_ENSURE_SUCCESS(mInternalWidget->GetBounds(bounds), NS_ERROR_FAILURE); + if (!mDocShell) { + if (aX) + *aX = mInitInfo->x; + if (aY) + *aY = mInitInfo->y; + if (aCX) + *aCX = mInitInfo->cx; + if (aCY) + *aCY = mInitInfo->cy; + } else if (mInternalWidget) { + nsIntRect bounds; + NS_ENSURE_SUCCESS(mInternalWidget->GetBounds(bounds), NS_ERROR_FAILURE); - if (aX) - *aX = bounds.x; - if (aY) - *aY = bounds.y; - if (aCX) - *aCX = bounds.width; - if (aCY) - *aCY = bounds.height; - return NS_OK; - } else { - // Can directly return this as it is the - // same interface, thus same returns. - return mDocShellAsWin->GetPositionAndSize(aX, aY, aCX, aCY); - } - return NS_OK; + if (aX) + *aX = bounds.x; + if (aY) + *aY = bounds.y; + if (aCX) + *aCX = bounds.width; + if (aCY) + *aCY = bounds.height; + return NS_OK; + } else { + // Can directly return this as it is the + // same interface, thus same returns. + return mDocShellAsWin->GetPositionAndSize(aX, aY, aCX, aCY); + } + return NS_OK; } NS_IMETHODIMP nsWebBrowser::Repaint(bool aForce) { - NS_ENSURE_STATE(mDocShell); - // Can directly return this as it is the - // same interface, thus same returns. - return mDocShellAsWin->Repaint(aForce); + NS_ENSURE_STATE(mDocShell); + // Can directly return this as it is the + // same interface, thus same returns. + return mDocShellAsWin->Repaint(aForce); } NS_IMETHODIMP nsWebBrowser::GetParentWidget(nsIWidget** aParentWidget) { - NS_ENSURE_ARG_POINTER(aParentWidget); + NS_ENSURE_ARG_POINTER(aParentWidget); - *aParentWidget = mParentWidget; + *aParentWidget = mParentWidget; - NS_IF_ADDREF(*aParentWidget); + NS_IF_ADDREF(*aParentWidget); - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsWebBrowser::SetParentWidget(nsIWidget* aParentWidget) { - NS_ENSURE_STATE(!mDocShell); + NS_ENSURE_STATE(!mDocShell); - mParentWidget = aParentWidget; - if (mParentWidget) - mParentNativeWindow = mParentWidget->GetNativeData(NS_NATIVE_WIDGET); - else - mParentNativeWindow = nullptr; + mParentWidget = aParentWidget; + if (mParentWidget) + mParentNativeWindow = mParentWidget->GetNativeData(NS_NATIVE_WIDGET); + else + mParentNativeWindow = nullptr; - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsWebBrowser::GetParentNativeWindow(nativeWindow* aParentNativeWindow) { - NS_ENSURE_ARG_POINTER(aParentNativeWindow); + NS_ENSURE_ARG_POINTER(aParentNativeWindow); - *aParentNativeWindow = mParentNativeWindow; + *aParentNativeWindow = mParentNativeWindow; - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsWebBrowser::SetParentNativeWindow(nativeWindow aParentNativeWindow) { - NS_ENSURE_STATE(!mDocShell); + NS_ENSURE_STATE(!mDocShell); - mParentNativeWindow = aParentNativeWindow; + mParentNativeWindow = aParentNativeWindow; - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsWebBrowser::GetNativeHandle(nsAString& aNativeHandle) { - // the nativeHandle should be accessed from nsIXULWindow - return NS_ERROR_NOT_IMPLEMENTED; + // the nativeHandle should be accessed from nsIXULWindow + return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP nsWebBrowser::GetVisibility(bool* visibility) { - NS_ENSURE_ARG_POINTER(visibility); + NS_ENSURE_ARG_POINTER(visibility); - if (!mDocShell) - *visibility = mInitInfo->visible; - else - NS_ENSURE_SUCCESS(mDocShellAsWin->GetVisibility(visibility), NS_ERROR_FAILURE); + if (!mDocShell) + *visibility = mInitInfo->visible; + else + NS_ENSURE_SUCCESS(mDocShellAsWin->GetVisibility(visibility), NS_ERROR_FAILURE); - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsWebBrowser::SetVisibility(bool aVisibility) { - if (!mDocShell) { - mInitInfo->visible = aVisibility; - } else { - NS_ENSURE_SUCCESS(mDocShellAsWin->SetVisibility(aVisibility), NS_ERROR_FAILURE); - if (mInternalWidget) { - mInternalWidget->Show(aVisibility); - } - } + if (!mDocShell) { + mInitInfo->visible = aVisibility; + } else { + NS_ENSURE_SUCCESS(mDocShellAsWin->SetVisibility(aVisibility), NS_ERROR_FAILURE); + if (mInternalWidget) { + mInternalWidget->Show(aVisibility); + } + } - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsWebBrowser::GetEnabled(bool* aEnabled) @@ -1394,16 +1412,16 @@ NS_IMETHODIMP nsWebBrowser::SetEnabled(bool aEnabled) NS_IMETHODIMP nsWebBrowser::GetMainWidget(nsIWidget** mainWidget) { - NS_ENSURE_ARG_POINTER(mainWidget); + NS_ENSURE_ARG_POINTER(mainWidget); - if (mInternalWidget) - *mainWidget = mInternalWidget; - else - *mainWidget = mParentWidget; + if (mInternalWidget) + *mainWidget = mInternalWidget; + else + *mainWidget = mParentWidget; - NS_IF_ADDREF(*mainWidget); + NS_IF_ADDREF(*mainWidget); - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsWebBrowser::SetFocus() @@ -1417,21 +1435,21 @@ NS_IMETHODIMP nsWebBrowser::SetFocus() NS_IMETHODIMP nsWebBrowser::GetTitle(char16_t** aTitle) { - NS_ENSURE_ARG_POINTER(aTitle); - NS_ENSURE_STATE(mDocShell); + NS_ENSURE_ARG_POINTER(aTitle); + NS_ENSURE_STATE(mDocShell); - NS_ENSURE_SUCCESS(mDocShellAsWin->GetTitle(aTitle), NS_ERROR_FAILURE); + NS_ENSURE_SUCCESS(mDocShellAsWin->GetTitle(aTitle), NS_ERROR_FAILURE); - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsWebBrowser::SetTitle(const char16_t* aTitle) { - NS_ENSURE_STATE(mDocShell); + NS_ENSURE_STATE(mDocShell); - NS_ENSURE_SUCCESS(mDocShellAsWin->SetTitle(aTitle), NS_ERROR_FAILURE); + NS_ENSURE_SUCCESS(mDocShellAsWin->SetTitle(aTitle), NS_ERROR_FAILURE); - return NS_OK; + return NS_OK; } //***************************************************************************** @@ -1439,30 +1457,30 @@ NS_IMETHODIMP nsWebBrowser::SetTitle(const char16_t* aTitle) //***************************************************************************** NS_IMETHODIMP nsWebBrowser::GetDefaultScrollbarPreferences(int32_t aScrollOrientation, - int32_t* aScrollbarPref) + int32_t* aScrollbarPref) { - NS_ENSURE_STATE(mDocShell); + NS_ENSURE_STATE(mDocShell); - return mDocShellAsScrollable->GetDefaultScrollbarPreferences(aScrollOrientation, - aScrollbarPref); + return mDocShellAsScrollable->GetDefaultScrollbarPreferences(aScrollOrientation, + aScrollbarPref); } NS_IMETHODIMP nsWebBrowser::SetDefaultScrollbarPreferences(int32_t aScrollOrientation, - int32_t aScrollbarPref) + int32_t aScrollbarPref) { - NS_ENSURE_STATE(mDocShell); + NS_ENSURE_STATE(mDocShell); - return mDocShellAsScrollable->SetDefaultScrollbarPreferences(aScrollOrientation, - aScrollbarPref); + return mDocShellAsScrollable->SetDefaultScrollbarPreferences(aScrollOrientation, + aScrollbarPref); } NS_IMETHODIMP nsWebBrowser::GetScrollbarVisibility(bool* aVerticalVisible, - bool* aHorizontalVisible) + bool* aHorizontalVisible) { - NS_ENSURE_STATE(mDocShell); + NS_ENSURE_STATE(mDocShell); - return mDocShellAsScrollable->GetScrollbarVisibility(aVerticalVisible, - aHorizontalVisible); + return mDocShellAsScrollable->GetScrollbarVisibility(aVerticalVisible, + aHorizontalVisible); } //***************************************************************************** @@ -1471,16 +1489,16 @@ NS_IMETHODIMP nsWebBrowser::GetScrollbarVisibility(bool* aVerticalVisible, NS_IMETHODIMP nsWebBrowser::ScrollByLines(int32_t aNumLines) { - NS_ENSURE_STATE(mDocShell); + NS_ENSURE_STATE(mDocShell); - return mDocShellAsTextScroll->ScrollByLines(aNumLines); + return mDocShellAsTextScroll->ScrollByLines(aNumLines); } NS_IMETHODIMP nsWebBrowser::ScrollByPages(int32_t aNumPages) { - NS_ENSURE_STATE(mDocShell); + NS_ENSURE_STATE(mDocShell); - return mDocShellAsTextScroll->ScrollByPages(aNumPages); + return mDocShellAsTextScroll->ScrollByPages(aNumPages); } @@ -1490,71 +1508,71 @@ NS_IMETHODIMP nsWebBrowser::ScrollByPages(int32_t aNumPages) NS_IMETHODIMP nsWebBrowser::SetDocShell(nsIDocShell* aDocShell) { - nsCOMPtr kungFuDeathGrip(mDocShell); - if (aDocShell) { - NS_ENSURE_TRUE(!mDocShell, NS_ERROR_FAILURE); + nsCOMPtr kungFuDeathGrip(mDocShell); + if (aDocShell) { + NS_ENSURE_TRUE(!mDocShell, NS_ERROR_FAILURE); - nsCOMPtr req(do_QueryInterface(aDocShell)); - nsCOMPtr baseWin(do_QueryInterface(aDocShell)); - nsCOMPtr nav(do_QueryInterface(aDocShell)); - nsCOMPtr scrollable(do_QueryInterface(aDocShell)); - nsCOMPtr textScroll(do_QueryInterface(aDocShell)); - nsCOMPtr progress(do_GetInterface(aDocShell)); - NS_ENSURE_TRUE(req && baseWin && nav && scrollable && textScroll && progress, - NS_ERROR_FAILURE); + nsCOMPtr req(do_QueryInterface(aDocShell)); + nsCOMPtr baseWin(do_QueryInterface(aDocShell)); + nsCOMPtr nav(do_QueryInterface(aDocShell)); + nsCOMPtr scrollable(do_QueryInterface(aDocShell)); + nsCOMPtr textScroll(do_QueryInterface(aDocShell)); + nsCOMPtr progress(do_GetInterface(aDocShell)); + NS_ENSURE_TRUE(req && baseWin && nav && scrollable && textScroll && progress, + NS_ERROR_FAILURE); - mDocShell = aDocShell; - mDocShellAsReq = req; - mDocShellAsWin = baseWin; - mDocShellAsNav = nav; - mDocShellAsScrollable = scrollable; - mDocShellAsTextScroll = textScroll; - mWebProgress = progress; + mDocShell = aDocShell; + mDocShellAsReq = req; + mDocShellAsWin = baseWin; + mDocShellAsNav = nav; + mDocShellAsScrollable = scrollable; + mDocShellAsTextScroll = textScroll; + mWebProgress = progress; - // By default, do not allow DNS prefetch, so we don't break our frozen - // API. Embeddors who decide to enable it should do so manually. - mDocShell->SetAllowDNSPrefetch(false); + // By default, do not allow DNS prefetch, so we don't break our frozen + // API. Embeddors who decide to enable it should do so manually. + mDocShell->SetAllowDNSPrefetch(false); - // It's possible to call setIsActive() on us before we have a docshell. - // If we're getting a docshell now, pass along our desired value. The - // default here (true) matches the default of the docshell, so this is - // a no-op unless setIsActive(false) has been called on us. - mDocShell->SetIsActive(mIsActive); - } else { - if (mDocShellTreeOwner) - mDocShellTreeOwner->RemoveFromWatcher(); // evil twin of Add in Create() - if (mDocShellAsWin) - mDocShellAsWin->Destroy(); + // It's possible to call setIsActive() on us before we have a docshell. + // If we're getting a docshell now, pass along our desired value. The + // default here (true) matches the default of the docshell, so this is + // a no-op unless setIsActive(false) has been called on us. + mDocShell->SetIsActive(mIsActive); + } else { + if (mDocShellTreeOwner) + mDocShellTreeOwner->RemoveFromWatcher(); // evil twin of Add in Create() + if (mDocShellAsWin) + mDocShellAsWin->Destroy(); - mDocShell = nullptr; - mDocShellAsReq = nullptr; - mDocShellAsWin = nullptr; - mDocShellAsNav = nullptr; - mDocShellAsScrollable = nullptr; - mDocShellAsTextScroll = nullptr; - mWebProgress = nullptr; - } + mDocShell = nullptr; + mDocShellAsReq = nullptr; + mDocShellAsWin = nullptr; + mDocShellAsNav = nullptr; + mDocShellAsScrollable = nullptr; + mDocShellAsTextScroll = nullptr; + mWebProgress = nullptr; + } - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsWebBrowser::EnsureDocShellTreeOwner() { - if (mDocShellTreeOwner) - return NS_OK; + if (mDocShellTreeOwner) + return NS_OK; - mDocShellTreeOwner = new nsDocShellTreeOwner(); - mDocShellTreeOwner->WebBrowser(this); + mDocShellTreeOwner = new nsDocShellTreeOwner(); + mDocShellTreeOwner->WebBrowser(this); - return NS_OK; + return NS_OK; } static void DrawPaintedLayer(PaintedLayer* aLayer, - gfxContext* aContext, - const nsIntRegion& aRegionToDraw, - DrawRegionClip aClip, - const nsIntRegion& aRegionToInvalidate, - void* aCallbackData) + gfxContext* aContext, + const nsIntRegion& aRegionToDraw, + DrawRegionClip aClip, + const nsIntRegion& aRegionToInvalidate, + void* aCallbackData) { DrawTarget& aDrawTarget = *aContext->GetDrawTarget(); @@ -1625,8 +1643,8 @@ NS_IMETHODIMP nsWebBrowser::GetPrimaryContentWindow(nsIDOMWindow** aDOMWindow) *aDOMWindow = domWindow; NS_ADDREF(*aDOMWindow); return NS_OK; - } + //***************************************************************************** // nsWebBrowser::nsIWebBrowserFocus //***************************************************************************** diff --git a/embedding/browser/nsWebBrowser.h b/embedding/browser/nsWebBrowser.h index f027362204cf..30e7894ddf14 100644 --- a/embedding/browser/nsWebBrowser.h +++ b/embedding/browser/nsWebBrowser.h @@ -1,6 +1,6 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * This Source Code Form is subject to the terms of the Mozilla Public +/* -*- 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/. */ @@ -46,25 +46,25 @@ class nsIContentViewerFile; class nsWebBrowserInitInfo { public: - //nsIBaseWindow Stuff - int32_t x; - int32_t y; - int32_t cx; - int32_t cy; - bool visible; - nsCOMPtr sessionHistory; - nsString name; + //nsIBaseWindow Stuff + int32_t x; + int32_t y; + int32_t cx; + int32_t cy; + bool visible; + nsCOMPtr sessionHistory; + nsString name; }; class nsWebBrowserListenerState { public: - bool Equals(nsIWeakReference *aListener, const nsIID& aID) { - return mWeakPtr.get() == aListener && mID.Equals(aID); - } + bool Equals(nsIWeakReference *aListener, const nsIID& aID) { + return mWeakPtr.get() == aListener && mID.Equals(aID); + } - nsWeakPtr mWeakPtr; - nsIID mID; + nsWeakPtr mWeakPtr; + nsIID mID; }; // {cda5863a-aa9c-411e-be49-ea0d525ab4b5} - @@ -87,79 +87,79 @@ class nsWebBrowser MOZ_FINAL : public nsIWebBrowser, public nsIWidgetListener, public nsSupportsWeakReference { -friend class nsDocShellTreeOwner; + friend class nsDocShellTreeOwner; public: - nsWebBrowser(); + nsWebBrowser(); - NS_DECL_ISUPPORTS + NS_DECL_ISUPPORTS - NS_DECL_NSIBASEWINDOW - NS_DECL_NSIDOCSHELLTREEITEM - NS_DECL_NSIINTERFACEREQUESTOR - NS_DECL_NSISCROLLABLE - NS_DECL_NSITEXTSCROLL - NS_DECL_NSIWEBBROWSER - NS_DECL_NSIWEBNAVIGATION - NS_DECL_NSIWEBBROWSERSETUP - NS_DECL_NSIWEBBROWSERPERSIST - NS_DECL_NSICANCELABLE - NS_DECL_NSIWEBBROWSERFOCUS - NS_DECL_NSIWEBBROWSERSTREAM - NS_DECL_NSIWEBPROGRESSLISTENER + NS_DECL_NSIBASEWINDOW + NS_DECL_NSIDOCSHELLTREEITEM + NS_DECL_NSIINTERFACEREQUESTOR + NS_DECL_NSISCROLLABLE + NS_DECL_NSITEXTSCROLL + NS_DECL_NSIWEBBROWSER + NS_DECL_NSIWEBNAVIGATION + NS_DECL_NSIWEBBROWSERSETUP + NS_DECL_NSIWEBBROWSERPERSIST + NS_DECL_NSICANCELABLE + NS_DECL_NSIWEBBROWSERFOCUS + NS_DECL_NSIWEBBROWSERSTREAM + NS_DECL_NSIWEBPROGRESSLISTENER protected: - virtual ~nsWebBrowser(); - NS_IMETHOD InternalDestroy(); + virtual ~nsWebBrowser(); + NS_IMETHOD InternalDestroy(); - // XXXbz why are these NS_IMETHOD? They're not interface methods! - NS_IMETHOD SetDocShell(nsIDocShell* aDocShell); - NS_IMETHOD EnsureDocShellTreeOwner(); - NS_IMETHOD GetPrimaryContentWindow(nsIDOMWindow **aDomWindow); - NS_IMETHOD BindListener(nsISupports *aListener, const nsIID& aIID); - NS_IMETHOD UnBindListener(nsISupports *aListener, const nsIID& aIID); - NS_IMETHOD EnableGlobalHistory(bool aEnable); + // XXXbz why are these NS_IMETHOD? They're not interface methods! + NS_IMETHOD SetDocShell(nsIDocShell* aDocShell); + NS_IMETHOD EnsureDocShellTreeOwner(); + NS_IMETHOD GetPrimaryContentWindow(nsIDOMWindow **aDomWindow); + NS_IMETHOD BindListener(nsISupports *aListener, const nsIID& aIID); + NS_IMETHOD UnBindListener(nsISupports *aListener, const nsIID& aIID); + NS_IMETHOD EnableGlobalHistory(bool aEnable); - // nsIWidgetListener - virtual void WindowRaised(nsIWidget* aWidget); - virtual void WindowLowered(nsIWidget* aWidget); - virtual bool PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion) MOZ_OVERRIDE; + // nsIWidgetListener + virtual void WindowRaised(nsIWidget* aWidget); + virtual void WindowLowered(nsIWidget* aWidget); + virtual bool PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion) MOZ_OVERRIDE; protected: - nsRefPtr mDocShellTreeOwner; - nsCOMPtr mDocShell; - nsCOMPtr mDocShellAsReq; - nsCOMPtr mDocShellAsWin; - nsCOMPtr mDocShellAsNav; - nsCOMPtr mDocShellAsScrollable; - nsCOMPtr mDocShellAsTextScroll; - nsCOMPtr mInternalWidget; - nsCOMPtr mWWatch; - nsAutoPtr mInitInfo; - uint32_t mContentType; - bool mActivating; - bool mShouldEnableHistory; - bool mIsActive; - nativeWindow mParentNativeWindow; - nsIWebProgressListener *mProgressListener; - nsCOMPtr mWebProgress; + nsRefPtr mDocShellTreeOwner; + nsCOMPtr mDocShell; + nsCOMPtr mDocShellAsReq; + nsCOMPtr mDocShellAsWin; + nsCOMPtr mDocShellAsNav; + nsCOMPtr mDocShellAsScrollable; + nsCOMPtr mDocShellAsTextScroll; + nsCOMPtr mInternalWidget; + nsCOMPtr mWWatch; + nsAutoPtr mInitInfo; + uint32_t mContentType; + bool mActivating; + bool mShouldEnableHistory; + bool mIsActive; + nativeWindow mParentNativeWindow; + nsIWebProgressListener *mProgressListener; + nsCOMPtr mWebProgress; - nsCOMPtr mPrintSettings; + nsCOMPtr mPrintSettings; - // cached background color - nscolor mBackgroundColor; + // cached background color + nscolor mBackgroundColor; - // persistence object - nsCOMPtr mPersist; - uint32_t mPersistCurrentState; - nsresult mPersistResult; - uint32_t mPersistFlags; + // persistence object + nsCOMPtr mPersist; + uint32_t mPersistCurrentState; + nsresult mPersistResult; + uint32_t mPersistFlags; - // stream - nsRefPtr mStream; + // stream + nsRefPtr mStream; - //Weak Reference interfaces... - nsIWidget* mParentWidget; - nsAutoPtr> mListenerArray; + //Weak Reference interfaces... + nsIWidget* mParentWidget; + nsAutoPtr> mListenerArray; }; #endif /* nsWebBrowser_h__ */ From 6c00639ed2d553f7240338ff4213012ecd8d9073 Mon Sep 17 00:00:00 2001 From: Andrew McCreight Date: Wed, 4 Feb 2015 15:15:12 -0800 Subject: [PATCH 43/74] Bug 1127430, part 3 - Fix even more braces in nsWebBrowser. r=smaug --- embedding/browser/nsWebBrowser.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/embedding/browser/nsWebBrowser.cpp b/embedding/browser/nsWebBrowser.cpp index 3b506d642927..7241991f4282 100644 --- a/embedding/browser/nsWebBrowser.cpp +++ b/embedding/browser/nsWebBrowser.cpp @@ -1282,26 +1282,34 @@ NS_IMETHODIMP nsWebBrowser::GetPositionAndSize(int32_t* aX, int32_t* aY, int32_t* aCX, int32_t* aCY) { if (!mDocShell) { - if (aX) + if (aX) { *aX = mInitInfo->x; - if (aY) + } + if (aY) { *aY = mInitInfo->y; - if (aCX) + } + if (aCX) { *aCX = mInitInfo->cx; - if (aCY) + } + if (aCY) { *aCY = mInitInfo->cy; + } } else if (mInternalWidget) { nsIntRect bounds; NS_ENSURE_SUCCESS(mInternalWidget->GetBounds(bounds), NS_ERROR_FAILURE); - if (aX) + if (aX) { *aX = bounds.x; - if (aY) + } + if (aY) { *aY = bounds.y; - if (aCX) + } + if (aCX) { *aCX = bounds.width; - if (aCY) + } + if (aCY) { *aCY = bounds.height; + } return NS_OK; } else { // Can directly return this as it is the From 7dbe705433843adde6d751923d5524756220b911 Mon Sep 17 00:00:00 2001 From: Andrew McCreight Date: Wed, 4 Feb 2015 15:15:12 -0800 Subject: [PATCH 44/74] Bug 1129015, part 1 - Remove trailing whitespace in docshell. r=smaug --- docshell/base/nsDocShell.cpp | 482 +++++++++++++++++------------------ docshell/base/nsDocShell.h | 20 +- 2 files changed, 251 insertions(+), 251 deletions(-) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index b35bc4c37d7e..1ea9640c409d 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -77,7 +77,7 @@ // we want to explore making the document own the load group // so we can associate the document URI with the load group. // until this point, we have an evil hack: -#include "nsIHttpChannelInternal.h" +#include "nsIHttpChannelInternal.h" #include "nsPILoadGroupInternal.h" // Local Includes @@ -237,7 +237,7 @@ nsIURIFixup *nsDocShell::sURIFixup = 0; // the pref on the creation of the first docshell. static uint32_t gValidateOrigin = 0xffffffff; -// Hint for native dispatch of events on how long to delay after +// Hint for native dispatch of events on how long to delay after // all documents have loaded in milliseconds before favoring normal // native event dispatch priorites over performance // Can be overridden with docshell.event_starvation_delay_hint pref. @@ -954,14 +954,14 @@ nsDocShell::Init() rv = nsDocLoader::AddDocLoaderAsChildOfRoot(this); NS_ENSURE_SUCCESS(rv, rv); - + // Add as |this| a progress listener to itself. A little weird, but // simpler than reproducing all the listener-notification logic in // overrides of the various methods via which nsDocLoader can be // notified. Note that this holds an nsWeakPtr to ourselves, so it's ok. return AddProgressListener(this, nsIWebProgress::NOTIFY_STATE_DOCUMENT | nsIWebProgress::NOTIFY_STATE_NETWORK); - + } void @@ -983,7 +983,7 @@ nsDocShell::DestroyChildren() //***************************************************************************** // nsDocShell::nsISupports -//***************************************************************************** +//***************************************************************************** NS_IMPL_ADDREF_INHERITED(nsDocShell, nsDocLoader) NS_IMPL_RELEASE_INHERITED(nsDocShell, nsDocLoader) @@ -1011,7 +1011,7 @@ NS_INTERFACE_MAP_END_INHERITING(nsDocLoader) ///***************************************************************************** // nsDocShell::nsIInterfaceRequestor -//***************************************************************************** +//***************************************************************************** NS_IMETHODIMP nsDocShell::GetInterface(const nsIID & aIID, void **aSink) { NS_PRECONDITION(aSink, "null out param"); @@ -1117,11 +1117,11 @@ NS_IMETHODIMP nsDocShell::GetInterface(const nsIID & aIID, void **aSink) *aSink = editingSession; NS_ADDREF((nsISupports *)*aSink); return NS_OK; - } + } - return NS_NOINTERFACE; + return NS_NOINTERFACE; } - else if (aIID.Equals(NS_GET_IID(nsIClipboardDragDropHookList)) + else if (aIID.Equals(NS_GET_IID(nsIClipboardDragDropHookList)) && NS_SUCCEEDED(EnsureTransferableHookData())) { *aSink = mTransferableHookData; NS_ADDREF((nsISupports *)*aSink); @@ -1130,7 +1130,7 @@ NS_IMETHODIMP nsDocShell::GetInterface(const nsIID & aIID, void **aSink) else if (aIID.Equals(NS_GET_IID(nsISelectionDisplay))) { nsIPresShell* shell = GetPresShell(); if (shell) - return shell->QueryInterface(aIID,aSink); + return shell->QueryInterface(aIID,aSink); } else if (aIID.Equals(NS_GET_IID(nsIDocShellTreeOwner))) { nsCOMPtr treeOwner; @@ -1322,11 +1322,11 @@ nsDocShell::ConvertLoadTypeToDocShellLoadInfo(uint32_t aLoadType) } return docShellLoadType; -} +} //***************************************************************************** // nsDocShell::nsIDocShell -//***************************************************************************** +//***************************************************************************** NS_IMETHODIMP nsDocShell::LoadURI(nsIURI * aURI, nsIDocShellLoadInfo * aLoadInfo, @@ -1336,7 +1336,7 @@ nsDocShell::LoadURI(nsIURI * aURI, NS_PRECONDITION(aLoadInfo || (aLoadFlags & EXTRA_LOAD_FLAGS) == 0, "Unexpected flags"); NS_PRECONDITION((aLoadFlags & 0xf) == 0, "Should not have these flags set"); - + // Note: we allow loads to get through here even if mFiredUnloadEvent is // true; that case will get handled in LoadInternal or LoadHistoryEntry, // so we pass false as the second parameter to IsNavigationAllowed. @@ -1366,7 +1366,7 @@ nsDocShell::LoadURI(nsIURI * aURI, nsCOMPtr sourceDocShell; nsCOMPtr baseURI; - uint32_t loadType = MAKE_LOAD_TYPE(LOAD_NORMAL, aLoadFlags); + uint32_t loadType = MAKE_LOAD_TYPE(LOAD_NORMAL, aLoadFlags); NS_ENSURE_ARG(aURI); @@ -1418,17 +1418,17 @@ nsDocShell::LoadURI(nsIURI * aURI, uint32_t parentLoadType; if (parentDS && parentDS != static_cast(this)) { - /* OK. It is a subframe. Checkout the + /* OK. It is a subframe. Checkout the * parent's loadtype. If the parent was loaded thro' a history * mechanism, then get the SH entry for the child from the parent. * This is done to restore frameset navigation while going back/forward. * If the parent was loaded through any other loadType, set the * child's loadType too accordingly, so that session history does not - * get confused. + * get confused. */ - + // Get the parent's load type - parentDS->GetLoadType(&parentLoadType); + parentDS->GetLoadType(&parentLoadType); // Get the ShEntry for the child from the parent nsCOMPtr currentSH; @@ -1444,10 +1444,10 @@ nsDocShell::LoadURI(nsIURI * aURI, parentDS->GetChildSHEntry(mChildOffset, getter_AddRefs(shEntry)); } - // Make some decisions on the child frame's loadType based on the - // parent's loadType. + // Make some decisions on the child frame's loadType based on the + // parent's loadType. if (mCurrentURI == nullptr) { - // This is a newly created frame. Check for exception cases first. + // This is a newly created frame. Check for exception cases first. // By default the subframe will inherit the parent's loadType. if (shEntry && (parentLoadType == LOAD_NORMAL || parentLoadType == LOAD_LINK || @@ -1456,7 +1456,7 @@ nsDocShell::LoadURI(nsIURI * aURI, // have a SHEntry. If it does, it could be because the parent is replacing an // existing frame with a new frame, in the onLoadHandler. We don't want this // url to get into session history. Clear off shEntry, and set load type to - // LOAD_BYPASS_HISTORY. + // LOAD_BYPASS_HISTORY. bool inOnLoadHandler=false; parentDS->GetIsExecutingOnLoadHandler(&inOnLoadHandler); if (inOnLoadHandler) { @@ -1468,14 +1468,14 @@ nsDocShell::LoadURI(nsIURI * aURI, // what comes thro' the pipe, not what's in history. shEntry = nullptr; } else if ((parentLoadType == LOAD_BYPASS_HISTORY) || - (shEntry && - ((parentLoadType & LOAD_CMD_HISTORY) || - (parentLoadType == LOAD_RELOAD_NORMAL) || + (shEntry && + ((parentLoadType & LOAD_CMD_HISTORY) || + (parentLoadType == LOAD_RELOAD_NORMAL) || (parentLoadType == LOAD_RELOAD_CHARSET_CHANGE)))) { // If the parent url, bypassed history or was loaded from - // history, pass on the parent's loadType to the new child + // history, pass on the parent's loadType to the new child // frame too, so that the child frame will also - // avoid getting into history. + // avoid getting into history. loadType = parentLoadType; } else if (parentLoadType == LOAD_ERROR_PAGE) { // If the parent document is an error page, we don't @@ -1492,30 +1492,30 @@ nsDocShell::LoadURI(nsIURI * aURI, } else { // This is a pre-existing subframe. If the load was not originally initiated // by session history, (if (!shEntry) condition succeeded) and mCurrentURI is not null, - // it is possible that a parent's onLoadHandler or even self's onLoadHandler is loading + // it is possible that a parent's onLoadHandler or even self's onLoadHandler is loading // a new page in this child. Check parent's and self's busy flag and if it is set, // we don't want this onLoadHandler load to get in to session history. uint32_t parentBusy = BUSY_FLAGS_NONE; uint32_t selfBusy = BUSY_FLAGS_NONE; - parentDS->GetBusyFlags(&parentBusy); + parentDS->GetBusyFlags(&parentBusy); GetBusyFlags(&selfBusy); if (parentBusy & BUSY_FLAGS_BUSY || selfBusy & BUSY_FLAGS_BUSY) { loadType = LOAD_NORMAL_REPLACE; - shEntry = nullptr; + shEntry = nullptr; } } } //parentDS - else { - // This is the root docshell. If we got here while - // executing an onLoad Handler,this load will not go + else { + // This is the root docshell. If we got here while + // executing an onLoad Handler,this load will not go // into session history. bool inOnLoadHandler=false; GetIsExecutingOnLoadHandler(&inOnLoadHandler); if (inOnLoadHandler) { loadType = LOAD_NORMAL_REPLACE; } - } + } } // !shEntry if (shEntry) { @@ -1567,7 +1567,7 @@ nsDocShell::LoadURI(nsIURI * aURI, // (4) we pass a null owner into the channel, and an owner will be // created later from the channel's internal data. // - // NOTE: This all only works because the only thing the owner is used + // NOTE: This all only works because the only thing the owner is used // for in InternalLoad is data:, javascript:, and about:blank // URIs. For other URIs this would all be dead wrong! @@ -1598,7 +1598,7 @@ nsDocShell::LoadURI(nsIURI * aURI, if (!sendReferrer) flags |= INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER; - + if (aLoadFlags & LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP) flags |= INTERNAL_LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP; @@ -1969,7 +1969,7 @@ nsDocShell::SetCurrentURI(nsIURI *aURI, nsIRequest *aRequest, } mCurrentURI = NS_TryToMakeImmutable(aURI); - + if (!NS_IsAboutBlank(mCurrentURI)) { mHasLoadedNonBlankURI = true; } @@ -1980,7 +1980,7 @@ nsDocShell::SetCurrentURI(nsIURI *aURI, nsIRequest *aRequest, nsCOMPtr root; GetSameTypeRootTreeItem(getter_AddRefs(root)); - if (root.get() == static_cast(this)) + if (root.get() == static_cast(this)) { // This is the root docshell isRoot = true; @@ -2008,12 +2008,12 @@ nsDocShell::SetCurrentURI(nsIURI *aURI, nsIRequest *aRequest, mURLSearchParams->ParseInput(search, nullptr); if (!isSubFrame && !isRoot) { - /* + /* * We don't want to send OnLocationChange notifications when * a subframe is being loaded for the first time, while * visiting a frameset page */ - return false; + return false; } if (aFireOnLocationChange) { @@ -2268,7 +2268,7 @@ NS_IMETHODIMP nsDocShell::GetUsePrivateBrowsing(bool* aUsePrivateBrowsing) { NS_ENSURE_ARG_POINTER(aUsePrivateBrowsing); - + *aUsePrivateBrowsing = mInPrivateBrowsing; return NS_OK; } @@ -2628,15 +2628,15 @@ nsDocShell::GetDocShellEnumerator(int32_t aItemType, int32_t aDirection, nsISimp { NS_ENSURE_ARG_POINTER(outEnum); *outEnum = nullptr; - + nsRefPtr docShellEnum; if (aDirection == ENUMERATE_FORWARDS) docShellEnum = new nsDocShellForwardsEnumerator; else docShellEnum = new nsDocShellBackwardsEnumerator; - + if (!docShellEnum) return NS_ERROR_OUT_OF_MEMORY; - + nsresult rv = docShellEnum->SetEnumDocShellType(aItemType); if (NS_FAILED(rv)) return rv; @@ -2739,7 +2739,7 @@ NS_IMETHODIMP nsDocShell::TabToTreeOwner(bool aForward, bool* aTookFocus) { NS_ENSURE_ARG_POINTER(aTookFocus); - + nsCOMPtr chromeFocus = do_GetInterface(mTreeOwner); if (chromeFocus) { if (aForward) @@ -2748,7 +2748,7 @@ nsDocShell::TabToTreeOwner(bool aForward, bool* aTookFocus) *aTookFocus = NS_SUCCEEDED(chromeFocus->FocusPrevElement()); } else *aTookFocus = false; - + return NS_OK; } @@ -2839,7 +2839,7 @@ nsDocShell::HistoryTransactionRemoved(int32_t aIndex) } else if (aIndex < mLoadedTransIndex) { --mLoadedTransIndex; } - + nsTObserverArray::ForwardIterator iter(mChildList); while (iter.HasMore()) { nsCOMPtr shell = do_QueryObject(iter.GetNext()); @@ -3128,7 +3128,7 @@ nsDocShell::AddSessionStorage(nsIPrincipal* aPrincipal, NS_IMETHODIMP nsDocShell::GetCurrentDocumentChannel(nsIChannel** aResult) { - NS_IF_ADDREF(*aResult = GetCurrentDocChannel()); + NS_IF_ADDREF(*aResult = GetCurrentDocChannel()); return NS_OK; } @@ -3227,7 +3227,7 @@ nsDocShell::NotifyScrollObservers() //***************************************************************************** // nsDocShell::nsIDocShellTreeItem -//***************************************************************************** +//***************************************************************************** NS_IMETHODIMP nsDocShell::GetName(nsAString& aName) @@ -3277,13 +3277,13 @@ nsDocShell::SetItemType(int32_t aItemType) nsCOMPtr docLoaderService = do_GetService(NS_DOCUMENTLOADER_SERVICE_CONTRACTID); NS_ENSURE_TRUE(docLoaderService, NS_ERROR_UNEXPECTED); - + NS_ENSURE_STATE(!mParent || mParent == docLoaderService); mItemType = aItemType; // disable auth prompting for anything but content - mAllowAuth = mItemType == typeContent; + mAllowAuth = mItemType == typeContent; nsRefPtr presContext = nullptr; GetPresContext(getter_AddRefs(presContext)); @@ -3436,7 +3436,7 @@ nsDocShell::SetDocLoaderParent(nsDocLoader * aParent) { SetPrivateBrowsing(value); } - + nsCOMPtr parentURIListener(do_GetInterface(parent)); if (parentURIListener) mContentListener->SetParentContentListener(parentURIListener); @@ -3538,7 +3538,7 @@ nsDocShell::CanAccessItem(nsIDocShellTreeItem* aTargetItem, // chrome? Should those get extra privileges? // For historical context, see: - // + // // Bug 13871: Prevent frameset spoofing // Bug 103638: Targets with same name in different windows open in wrong // window with javascript @@ -3589,7 +3589,7 @@ nsDocShell::CanAccessItem(nsIDocShellTreeItem* aTargetItem, if (ValidateOrigin(aAccessingItem, target)) { return true; } - + nsCOMPtr parent; target->GetSameTypeParent(getter_AddRefs(parent)); parent.swap(target); @@ -3625,7 +3625,7 @@ nsDocShell::CanAccessItem(nsIDocShellTreeItem* aTargetItem, return false; } - return CanAccessItem(openerItem, aAccessingItem, false); + return CanAccessItem(openerItem, aAccessingItem, false); } static bool @@ -3714,7 +3714,7 @@ nsDocShell::FindItemWithName(const char16_t * aName, // Note: _content should always exist. If we don't have one // hanging off the treeowner, just create a named window.... // so don't return here, in case we did that and can now find - // it. + // it. // XXXbz should we be using |root| instead of creating // a new window? } @@ -3766,7 +3766,7 @@ nsDocShell::DoFindItemWithName(const char16_t* aName, "FindChildWithName should not be failing here."); if (*_retval) return NS_OK; - + // Third if we have a parent and it isn't the requestor then we // should ask it to do the search. If it is the requestor we // should just stop here and let the parent do the rest. If we @@ -3883,7 +3883,7 @@ nsDocShell::GetTreeOwner(nsIDocShellTreeOwner ** aTreeOwner) } #ifdef DEBUG_DOCSHELL_FOCUS -static void +static void PrintDocTree(nsIDocShellTreeItem * aParentNode, int aLevel) { for (int32_t i=0;iGetRootElement(); - printf("DS %p Ty %s Doc %p DW %p EM %p CN %p\n", - (void*)parentAsDocShell.get(), - type==nsIDocShellTreeItem::typeChrome?"Chr":"Con", + printf("DS %p Ty %s Doc %p DW %p EM %p CN %p\n", + (void*)parentAsDocShell.get(), + type==nsIDocShellTreeItem::typeChrome?"Chr":"Con", (void*)doc, (void*)domwin.get(), (void*)presContext->EventStateManager(), (void*)rootElement); @@ -3921,7 +3921,7 @@ PrintDocTree(nsIDocShellTreeItem * aParentNode, int aLevel) } } -static void +static void PrintDocTree(nsIDocShellTreeItem * aParentNode) { NS_ASSERTION(aParentNode, "Pointer is null!"); @@ -3983,7 +3983,7 @@ nsDocShell::SetTreeOwner(nsIDocShellTreeOwner * aTreeOwner) while (iter.HasMore()) { nsCOMPtr child = do_QueryObject(iter.GetNext()); NS_ENSURE_TRUE(child, NS_ERROR_FAILURE); - + if (child->ItemType() == mItemType) child->SetTreeOwner(aTreeOwner); } @@ -4048,7 +4048,7 @@ nsDocShell::AddChild(nsIDocShellTreeItem * aChild) } ancestor = ancestor->GetParent(); } while (ancestor); - + // Make sure to remove the child from its current parent. nsDocLoader* childsParent = childAsDocLoader->GetParent(); if (childsParent) { @@ -4058,7 +4058,7 @@ nsDocShell::AddChild(nsIDocShellTreeItem * aChild) // Make sure to clear the treeowner in case this child is a different type // from us. aChild->SetTreeOwner(nullptr); - + nsresult res = AddChildLoader(childAsDocLoader); NS_ENSURE_SUCCESS(res, res); NS_ASSERTION(!mChildList.IsEmpty(), @@ -4098,7 +4098,7 @@ nsDocShell::AddChild(nsIDocShellTreeItem * aChild) // to it. We'll later use that field, in the loading process, for the // charset choosing algorithm. // If we fail, at any point, we just return NS_OK. - // This code has some performance impact. But this will be reduced when + // This code has some performance impact. But this will be reduced when // the current charset will finally be stored as an Atom, avoiding the // alias resolution extra look-up. @@ -4117,7 +4117,7 @@ nsDocShell::AddChild(nsIDocShellTreeItem * aChild) if (mCurrentURI) { // Check if the url is wyciwyg - mCurrentURI->SchemeIs("wyciwyg", &isWyciwyg); + mCurrentURI->SchemeIs("wyciwyg", &isWyciwyg); } if (!isWyciwyg) { @@ -4146,10 +4146,10 @@ nsDocShell::RemoveChild(nsIDocShellTreeItem * aChild) nsRefPtr childAsDocLoader = GetAsDocLoader(aChild); NS_ENSURE_TRUE(childAsDocLoader, NS_ERROR_UNEXPECTED); - + nsresult rv = RemoveChildLoader(childAsDocLoader); NS_ENSURE_SUCCESS(rv, rv); - + aChild->SetTreeOwner(nullptr); return nsDocLoader::AddDocLoaderAsChildOfRoot(childAsDocLoader); @@ -4170,7 +4170,7 @@ nsDocShell::GetChildAt(int32_t aIndex, nsIDocShellTreeItem ** aChild) nsIDocumentLoader* child = ChildAt(aIndex); NS_ENSURE_TRUE(child, NS_ERROR_UNEXPECTED); - + return CallQueryInterface(child, aChild); } @@ -4184,7 +4184,7 @@ nsDocShell::FindChildWithName(const char16_t * aName, NS_ENSURE_ARG(aName); NS_ENSURE_ARG_POINTER(_retval); - *_retval = nullptr; // if we don't find one, we return NS_OK and a null result + *_retval = nullptr; // if we don't find one, we return NS_OK and a null result if (!*aName) return NS_OK; @@ -4239,32 +4239,32 @@ nsDocShell::GetChildSHEntry(int32_t aChildOffset, nsISHEntry ** aResult) NS_ENSURE_ARG_POINTER(aResult); *aResult = nullptr; - + // A nsISHEntry for a child is *only* available when the parent is in // the progress of loading a document too... - + if (mLSHE) { /* Before looking for the subframe's url, check * the expiration status of the parent. If the parent - * has expired from cache, then subframes will not be - * loaded from history in certain situations. + * has expired from cache, then subframes will not be + * loaded from history in certain situations. */ bool parentExpired=false; mLSHE->GetExpirationStatus(&parentExpired); - + /* Get the parent's Load Type so that it can be set on the child too. * By default give a loadHistory value */ uint32_t loadType = nsIDocShellLoadInfo::loadHistory; - mLSHE->GetLoadType(&loadType); - // If the user did a shift-reload on this frameset page, + mLSHE->GetLoadType(&loadType); + // If the user did a shift-reload on this frameset page, // we don't want to load the subframes from history. if (loadType == nsIDocShellLoadInfo::loadReloadBypassCache || loadType == nsIDocShellLoadInfo::loadReloadBypassProxy || loadType == nsIDocShellLoadInfo::loadReloadBypassProxyAndCache || loadType == nsIDocShellLoadInfo::loadRefresh) return rv; - + /* If the user pressed reload and the parent frame has expired * from cache, we do not want to load the child frame from history. */ @@ -4277,9 +4277,9 @@ nsDocShell::GetChildSHEntry(int32_t aChildOffset, nsISHEntry ** aResult) nsCOMPtr container(do_QueryInterface(mLSHE)); if (container) { // Get the child subframe from session history. - rv = container->GetChildAt(aChildOffset, aResult); - if (*aResult) - (*aResult)->SetLoadType(loadType); + rv = container->GetChildAt(aChildOffset, aResult); + if (*aResult) + (*aResult)->SetLoadType(loadType); } } return rv; @@ -4293,7 +4293,7 @@ nsDocShell::AddChildSHEntry(nsISHEntry * aCloneRef, nsISHEntry * aNewEntry, nsresult rv = NS_OK; if (mLSHE && loadType != LOAD_PUSHSTATE) { - /* You get here if you are currently building a + /* You get here if you are currently building a * hierarchy ie.,you just visited a frameset page */ nsCOMPtr container(do_QueryInterface(mLSHE, &rv)); @@ -4327,7 +4327,7 @@ nsDocShell::AddChildSHEntryInternal(nsISHEntry* aCloneRef, if (mSessionHistory) { /* You are currently in the rootDocShell. * You will get here when a subframe has a new url - * to load and you have walked up the tree all the + * to load and you have walked up the tree all the * way to the top to clone the current SHEntry hierarchy * and replace the subframe where a new url was loaded with * a new entry. @@ -4376,7 +4376,7 @@ nsDocShell::AddChildSHEntryToParent(nsISHEntry* aNewEntry, int32_t aChildOffset, bool aCloneChildren) { /* You will get here when you are in a subframe and - * a new url has been loaded on you. + * a new url has been loaded on you. * The mOSHE in this subframe will be the previous url's * mOSHE. This mOSHE will be used as the identification * for this subframe in the CloneAndReplace function. @@ -4571,7 +4571,7 @@ nsDocShell::ClearFrameHistory(nsISHEntry* aEntry) //------------------------------------- //-- Helper Method for Print discovery //------------------------------------- -bool +bool nsDocShell::IsPrintingOrPP(bool aDisplayErrorDialog) { if (mIsPrintingOrPP && aDisplayErrorDialog) { @@ -4600,7 +4600,7 @@ nsDocShell::IsNavigationAllowed(bool aDisplayPrintErrorDialog, //***************************************************************************** // nsDocShell::nsIWebNavigation -//***************************************************************************** +//***************************************************************************** NS_IMETHODIMP nsDocShell::GetCanGoBack(bool * aCanGoBack) @@ -4614,7 +4614,7 @@ nsDocShell::GetCanGoBack(bool * aCanGoBack) rv = GetRootSessionHistory(getter_AddRefs(rootSH)); nsCOMPtr webnav(do_QueryInterface(rootSH)); NS_ENSURE_TRUE(webnav, NS_ERROR_FAILURE); - rv = webnav->GetCanGoBack(aCanGoBack); + rv = webnav->GetCanGoBack(aCanGoBack); return rv; } @@ -4628,7 +4628,7 @@ nsDocShell::GetCanGoForward(bool * aCanGoForward) } nsresult rv; nsCOMPtr rootSH; - rv = GetRootSessionHistory(getter_AddRefs(rootSH)); + rv = GetRootSessionHistory(getter_AddRefs(rootSH)); nsCOMPtr webnav(do_QueryInterface(rootSH)); NS_ENSURE_TRUE(webnav, NS_ERROR_FAILURE); rv = webnav->GetCanGoForward(aCanGoForward); @@ -4703,7 +4703,7 @@ nsDocShell::LoadURIWithBase(const char16_t * aURI, nsIURI * aBaseURI) { NS_ASSERTION((aLoadFlags & 0xf) == 0, "Unexpected flags"); - + if (!IsNavigationAllowed()) { return NS_OK; // JS may not handle returning of an error code } @@ -4726,7 +4726,7 @@ nsDocShell::LoadURIWithBase(const char16_t * aURI, if (uri) { aLoadFlags &= ~LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP; } - + nsCOMPtr fixupInfo; if (sURIFixup) { // Call the fixup object. This will clobber the rv from NS_NewURI @@ -4821,7 +4821,7 @@ nsDocShell::LoadURIWithBase(const char16_t * aURI, // Save URI string in case it's needed later when // sending to search engine service in EndPageLoad() - mOriginalUriString = uriString; + mOriginalUriString = uriString; return rv; } @@ -4988,7 +4988,7 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI, if (alternateErrorPage) errorPage.Assign(alternateErrorPage); - if (!IsFrame() && errorPage.EqualsIgnoreCase("certerror")) + if (!IsFrame() && errorPage.EqualsIgnoreCase("certerror")) mozilla::Telemetry::Accumulate(mozilla::Telemetry::SECURITY_UI, bucketId); } else { @@ -5186,7 +5186,7 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI, // Display an error page LoadErrorPage(aURI, aURL, errorPage.get(), error.get(), messageStr.get(), cssClass.get(), aFailedChannel); - } + } else { // The prompter reqires that our private window has a document (or it @@ -5592,7 +5592,7 @@ nsDocShell::GetCurrentDescriptor(nsISupports **aPageDescriptor) // null out inappropriate cloned attributes... dest->SetParent(nullptr); dest->SetIsSubFrame(false); - + return CallQueryInterface(dest, aPageDescriptor); } @@ -5602,7 +5602,7 @@ nsDocShell::GetCurrentDescriptor(nsISupports **aPageDescriptor) //***************************************************************************** // nsDocShell::nsIBaseWindow -//***************************************************************************** +//***************************************************************************** NS_IMETHODIMP nsDocShell::InitWindow(nativeWindow parentNativeWindow, @@ -5640,8 +5640,8 @@ nsDocShell::Create() Preferences::GetBool("browser.xul.error_pages.enabled", mUseErrorPages); if(!gAddedPreferencesVarCache) { - Preferences::AddBoolVarCache(&sUseErrorPages, - "browser.xul.error_pages.enabled", + Preferences::AddBoolVarCache(&sUseErrorPages, + "browser.xul.error_pages.enabled", mUseErrorPages); gAddedPreferencesVarCache = true; } @@ -5674,7 +5674,7 @@ nsDocShell::Destroy() serv->NotifyObservers(GetAsSupports(this), msg, nullptr); } } - + mIsBeingDestroyed = true; // Make sure we don't record profile timeline markers anymore @@ -5698,7 +5698,7 @@ nsDocShell::Destroy() mOSHE->SetEditorData(nullptr); if (mLSHE) mLSHE->SetEditorData(nullptr); - + // Note: mContentListener can be null if Init() failed and we're being // called from the destructor. if (mContentListener) { @@ -5736,7 +5736,7 @@ nsDocShell::Destroy() } nsDocLoader::Destroy(); - + mParentWidget = nullptr; mCurrentURI = nullptr; @@ -5872,7 +5872,7 @@ nsDocShell::GetPositionAndSize(int32_t * x, int32_t * y, int32_t * cx, doc->FlushPendingNotifications(Flush_Layout); } } - + DoGetPositionAndSize(x, y, cx, cy); return NS_OK; } @@ -5880,7 +5880,7 @@ nsDocShell::GetPositionAndSize(int32_t * x, int32_t * y, int32_t * cx, void nsDocShell::DoGetPositionAndSize(int32_t * x, int32_t * y, int32_t * cx, int32_t * cy) -{ +{ if (x) *x = mBounds.x; if (y) @@ -5976,7 +5976,7 @@ nsDocShell::GetVisibility(bool * aVisibility) return NS_OK; // otherwise, we must walk up the document and view trees checking - // for a hidden view, unless we're an off screen browser, which + // for a hidden view, unless we're an off screen browser, which // would make this test meaningless. nsRefPtr docShell = this; @@ -6029,14 +6029,14 @@ nsDocShell::GetVisibility(bool * aVisibility) } NS_IMETHODIMP -nsDocShell::SetIsOffScreenBrowser(bool aIsOffScreen) +nsDocShell::SetIsOffScreenBrowser(bool aIsOffScreen) { mIsOffScreenBrowser = aIsOffScreen; return NS_OK; } NS_IMETHODIMP -nsDocShell::GetIsOffScreenBrowser(bool *aIsOffScreen) +nsDocShell::GetIsOffScreenBrowser(bool *aIsOffScreen) { *aIsOffScreen = mIsOffScreenBrowser; return NS_OK; @@ -6202,7 +6202,7 @@ nsDocShell::SetMixedContentChannel(nsIChannel* aMixedContentChannel) nsCOMPtr root; GetSameTypeRootTreeItem(getter_AddRefs(root)); NS_WARN_IF_FALSE( - root.get() == static_cast(this), + root.get() == static_cast(this), "Setting mMixedContentChannel on a docshell that is not the root docshell" ); } @@ -6283,7 +6283,7 @@ nsDocShell::SetVisibility(bool aVisibility) else { cv->Hide(); } - + return NS_OK; } @@ -6310,7 +6310,7 @@ nsDocShell::SetFocus() NS_IMETHODIMP nsDocShell::GetMainWidget(nsIWidget ** aMainWidget) { - // We don't create our own widget, so simply return the parent one. + // We don't create our own widget, so simply return the parent one. return GetParentWidget(aMainWidget); } @@ -6332,7 +6332,7 @@ nsDocShell::SetTitle(const char16_t * aTitle) nsCOMPtr parent; GetSameTypeParent(getter_AddRefs(parent)); - // When title is set on the top object it should then be passed to the + // When title is set on the top object it should then be passed to the // tree owner. if (!parent) { nsCOMPtr @@ -6356,7 +6356,7 @@ nsDocShell::SetTitle(const char16_t * aTitle) if (mOSHE && mLoadType != LOAD_BYPASS_HISTORY && mLoadType != LOAD_ERROR_PAGE) { - mOSHE->SetTitle(mTitle); + mOSHE->SetTitle(mTitle); } return NS_OK; @@ -6399,7 +6399,7 @@ nsDocShell::SetCurScrollPosEx(int32_t curHorizontalPos, int32_t curVerticalPos) //***************************************************************************** // nsDocShell::nsIScrollable -//***************************************************************************** +//***************************************************************************** NS_IMETHODIMP nsDocShell::GetDefaultScrollbarPreferences(int32_t scrollOrientation, @@ -6458,7 +6458,7 @@ nsDocShell::GetScrollbarVisibility(bool * verticalVisible, //***************************************************************************** // nsDocShell::nsITextScroll -//***************************************************************************** +//***************************************************************************** NS_IMETHODIMP nsDocShell::ScrollByLines(int32_t numLines) @@ -6484,7 +6484,7 @@ nsDocShell::ScrollByPages(int32_t numPages) //***************************************************************************** // nsDocShell::nsIRefreshURI -//***************************************************************************** +//***************************************************************************** NS_IMETHODIMP nsDocShell::RefreshURI(nsIURI * aURI, int32_t aDelay, bool aRepeat, @@ -6533,7 +6533,7 @@ nsDocShell::RefreshURI(nsIURI * aURI, int32_t aDelay, bool aRepeat, if (busyFlags & BUSY_FLAGS_BUSY) { // We are busy loading another page. Don't create the // timer right now. Instead queue up the request and trigger the - // timer in EndPageLoad(). + // timer in EndPageLoad(). mRefreshURIList->AppendElement(refreshTimer); } else { @@ -6550,7 +6550,7 @@ nsDocShell::RefreshURI(nsIURI * aURI, int32_t aDelay, bool aRepeat, nsresult nsDocShell::ForceRefreshURIFromTimer(nsIURI * aURI, - int32_t aDelay, + int32_t aDelay, bool aMetaRefresh, nsITimer* aTimer) { @@ -6604,7 +6604,7 @@ nsDocShell::DoAppRedirectIfNeeded(nsIURI * aURI, NS_IMETHODIMP nsDocShell::ForceRefreshURI(nsIURI * aURI, - int32_t aDelay, + int32_t aDelay, bool aMetaRefresh) { NS_ENSURE_ARG(aURI); @@ -6629,7 +6629,7 @@ nsDocShell::ForceRefreshURI(nsIURI * aURI, loadInfo->SetOwnerIsExplicit(true); /* Check if this META refresh causes a redirection - * to another site. + * to another site. */ bool equalUri = false; nsresult rv = aURI->Equals(mCurrentURI, &equalUri); @@ -6641,7 +6641,7 @@ nsDocShell::ForceRefreshURI(nsIURI * aURI, * Pass a REPLACE flag to LoadURI(). */ loadInfo->SetLoadType(nsIDocShellLoadInfo::loadNormalReplace); - + /* for redirects we mimic HTTP, which passes the * original referrer */ @@ -6678,14 +6678,14 @@ nsDocShell::SetupRefreshURIFromHeader(nsIURI * aBaseURI, // Also note that the seconds and URL separator can be either // a ';' or a ','. The ',' separator should be illegal but CNN // is using it. - // + // // We need to handle the following strings, where // - X is a set of digits // - URI is either a relative or absolute URI // // Note that URI should start with "url=" but we allow omission // - // "" || ";" || "," + // "" || ";" || "," // empty string. use the currently loaded URI // and refresh immediately. // "X" || "X;" || "X," @@ -6694,14 +6694,14 @@ nsDocShell::SetupRefreshURIFromHeader(nsIURI * aBaseURI, // Refresh using URI as the destination in X seconds. // "URI" || "; URI" || ", URI" // Refresh immediately using URI as the destination. - // + // // Currently, anything immediately following the URI, if // separated by any char in the set "'\"\t\r\n " will be // ignored. So "10; url=go.html ; foo=bar" will work, // and so will "10; url='go.html'; foo=bar". However, // "10; url=go.html; foo=bar" will result in the uri // "go.html;" since ';' and ',' are valid uri characters. - // + // // Note that we need to remove any tokens wrapping the URI. // These tokens currently include spaces, double and single // quotes. @@ -6944,7 +6944,7 @@ DoCancelRefreshURITimers(nsISupportsArray* aTimerList) aTimerList->RemoveElementAt(n); // bye bye owning timer ref if (timer) - timer->Cancel(); + timer->Cancel(); } } @@ -7039,29 +7039,29 @@ nsDocShell::RefreshURIFromQueue() mRefreshURIList->GetElementAt(--n, getter_AddRefs(element)); nsCOMPtr refreshInfo(do_QueryInterface(element)); - if (refreshInfo) { + if (refreshInfo) { // This is the nsRefreshTimer object, waiting to be - // setup in a timer object and fired. + // setup in a timer object and fired. // Create the timer and trigger it. uint32_t delay = static_cast(static_cast(refreshInfo))->GetDelay(); nsCOMPtr timer = do_CreateInstance("@mozilla.org/timer;1"); - if (timer) { + if (timer) { // Replace the nsRefreshTimer element in the queue with // its corresponding timer object, so that in case another // load comes through before the timer can go off, the timer will // get cancelled in CancelRefreshURITimer() mRefreshURIList->ReplaceElementAt(timer, n); timer->InitWithCallback(refreshInfo, delay, nsITimer::TYPE_ONE_SHOT); - } - } + } + } } // while - + return NS_OK; } //***************************************************************************** // nsDocShell::nsIContentViewerContainer -//***************************************************************************** +//***************************************************************************** NS_IMETHODIMP nsDocShell::Embed(nsIContentViewer * aContentViewer, @@ -7074,7 +7074,7 @@ nsDocShell::Embed(nsIContentViewer * aContentViewer, nsresult rv = SetupNewViewer(aContentViewer); NS_ENSURE_SUCCESS(rv, rv); - // If we are loading a wyciwyg url from history, change the base URI for + // If we are loading a wyciwyg url from history, change the base URI for // the document to the original http url that created the document.write(). // This makes sure that all relative urls in a document.written page loaded // via history work properly. @@ -7084,7 +7084,7 @@ nsDocShell::Embed(nsIContentViewer * aContentViewer, mLoadType == LOAD_RELOAD_CHARSET_CHANGE)){ bool isWyciwyg = false; // Check if the url is wyciwyg - rv = mCurrentURI->SchemeIs("wyciwyg", &isWyciwyg); + rv = mCurrentURI->SchemeIs("wyciwyg", &isWyciwyg); if (isWyciwyg && NS_SUCCEEDED(rv)) SetBaseUrlForWyciwyg(aContentViewer); } @@ -7123,7 +7123,7 @@ nsDocShell::Embed(nsIContentViewer * aContentViewer, } /* void setIsPrinting (in boolean aIsPrinting); */ -NS_IMETHODIMP +NS_IMETHODIMP nsDocShell::SetIsPrinting(bool aIsPrinting) { mIsPrintingOrPP = aIsPrinting; @@ -7132,7 +7132,7 @@ nsDocShell::SetIsPrinting(bool aIsPrinting) //***************************************************************************** // nsDocShell::nsIWebProgressListener -//***************************************************************************** +//***************************************************************************** NS_IMETHODIMP nsDocShell::OnProgressChange(nsIWebProgress * aProgress, @@ -7171,7 +7171,7 @@ nsDocShell::OnStateChange(nsIWebProgress * aProgress, nsIRequest * aRequest, if (wcwgChannel && !mLSHE && (mItemType == typeContent) && aProgress == webProgress.get()) { bool equalUri = true; // Store the wyciwyg url in session history, only if it is - // being loaded fresh for the first time. We don't want + // being loaded fresh for the first time. We don't want // multiple entries for successive loads if (mCurrentURI && NS_SUCCEEDED(uri->Equals(mCurrentURI, &equalUri)) && @@ -7214,7 +7214,7 @@ nsDocShell::OnStateChange(nsIWebProgress * aProgress, nsIRequest * aRequest, // and SetHistoryEntry now. SetHistoryEntry(&mOSHE, mLSHE); } - + } // Page has begun to load mBusyFlags = BUSY_FLAGS_BUSY | BUSY_FLAGS_BEFORE_PAGE_LOAD; @@ -7356,7 +7356,7 @@ nsDocShell::OnRedirectStateChange(nsIChannel* aOldChannel, } } - if (!(aRedirectFlags & nsIChannelEventSink::REDIRECT_INTERNAL) && + if (!(aRedirectFlags & nsIChannelEventSink::REDIRECT_INTERNAL) && mLoadType & (LOAD_CMD_RELOAD | LOAD_CMD_HISTORY)) { mLoadType = LOAD_NORMAL_REPLACE; SetHistoryEntry(&mLSHE, nullptr); @@ -7387,7 +7387,7 @@ nsDocShell::EndPageLoad(nsIWebProgress * aProgress, { if(!aChannel) return NS_ERROR_NULL_POINTER; - + MOZ_EVENT_TRACER_DONE(this, "docshell::pageload"); nsCOMPtr url; @@ -7416,14 +7416,14 @@ nsDocShell::EndPageLoad(nsIWebProgress * aProgress, // clean up reload state for meta charset if (eCharsetReloadRequested == mCharsetReloadState) mCharsetReloadState = eCharsetReloadStopOrigional; - else + else mCharsetReloadState = eCharsetReloadInit; // Save a pointer to the currently-loading history entry. // nsDocShell::EndPageLoad will clear mLSHE, but we may need this history // entry further down in this method. nsCOMPtr loadingSHE = mLSHE; - + // // one of many safeguards that prevent death and destruction if // someone is so very very rude as to bring this window down @@ -7444,25 +7444,25 @@ nsDocShell::EndPageLoad(nsIWebProgress * aProgress, // favor native event dispatch priorities // over performance if (--gNumberOfDocumentsLoading == 0) { - // Hint to use normal native event dispatch priorities + // Hint to use normal native event dispatch priorities FavorPerformanceHint(false); } } /* Check if the httpChannel has any cache-control related response headers, - * like no-store, no-cache. If so, update SHEntry so that - * when a user goes back/forward to this page, we appropriately do + * like no-store, no-cache. If so, update SHEntry so that + * when a user goes back/forward to this page, we appropriately do * form value restoration or load from server. */ nsCOMPtr httpChannel(do_QueryInterface(aChannel)); - if (!httpChannel) // HttpChannel could be hiding underneath a Multipart channel. + if (!httpChannel) // HttpChannel could be hiding underneath a Multipart channel. GetHttpChannel(aChannel, getter_AddRefs(httpChannel)); if (httpChannel) { // figure out if SH should be saving layout state. - bool discardLayoutState = ShouldDiscardLayoutState(httpChannel); + bool discardLayoutState = ShouldDiscardLayoutState(httpChannel); if (mLSHE && discardLayoutState && (mLoadType & LOAD_CMD_NORMAL) && (mLoadType != LOAD_BYPASS_HISTORY) && (mLoadType != LOAD_ERROR_PAGE)) - mLSHE->SetSaveLayoutStateFlag(false); + mLSHE->SetSaveLayoutStateFlag(false); } // Clear mLSHE after calling the onLoadHandlers. This way, if the @@ -7476,7 +7476,7 @@ nsDocShell::EndPageLoad(nsIWebProgress * aProgress, SetHistoryEntry(&mLSHE, nullptr); } // if there's a refresh header in the channel, this method - // will set it up for us. + // will set it up for us. RefreshURIFromQueue(); // Test whether this is the top frame or a subframe @@ -7550,7 +7550,7 @@ nsDocShell::EndPageLoad(nsIWebProgress * aProgress, nsAutoCString oldSpec; url->GetSpec(oldSpec); - + // // First try keyword fixup // @@ -7638,7 +7638,7 @@ nsDocShell::EndPageLoad(nsIWebProgress * aProgress, // Skip fixup for anything except a normal document load // operation on the topframe. - + if (mLoadType != LOAD_NORMAL || !isTopFrame) { doCreateAlternate = false; } @@ -7696,9 +7696,9 @@ nsDocShell::EndPageLoad(nsIWebProgress * aProgress, // It is time to throw an error dialog box, and be done with it... // Errors to be shown only on top-level frames - if ((aStatus == NS_ERROR_UNKNOWN_HOST || + if ((aStatus == NS_ERROR_UNKNOWN_HOST || aStatus == NS_ERROR_CONNECTION_REFUSED || - aStatus == NS_ERROR_UNKNOWN_PROXY_HOST || + aStatus == NS_ERROR_UNKNOWN_PROXY_HOST || aStatus == NS_ERROR_PROXY_CONNECTION_REFUSED) && (isTopFrame || UseErrorPages())) { DisplayLoadError(aStatus, url, nullptr, aChannel); @@ -7737,7 +7737,7 @@ nsDocShell::EndPageLoad(nsIWebProgress * aProgress, //***************************************************************************** // nsDocShell: Content Viewer Management -//***************************************************************************** +//***************************************************************************** nsresult nsDocShell::EnsureContentViewer() @@ -7799,7 +7799,7 @@ nsDocShell::CreateAboutBlankContentViewer(nsIPrincipal* aPrincipal, // mContentViewer->PermitUnload may release |this| docshell. nsCOMPtr kungFuDeathGrip(this); - + // Make sure timing is created. But first record whether we had it // already, so we don't clobber the timing for an in-progress load. bool hadTiming = mTiming; @@ -7822,7 +7822,7 @@ nsDocShell::CreateAboutBlankContentViewer(nsIPrincipal* aPrincipal, return NS_ERROR_FAILURE; } - mSavingOldViewer = aTryToSaveOldPresentation && + mSavingOldViewer = aTryToSaveOldPresentation && CanSavePresentation(LOAD_NORMAL, nullptr, nullptr); if (mTiming) { @@ -7832,7 +7832,7 @@ nsDocShell::CreateAboutBlankContentViewer(nsIPrincipal* aPrincipal, // Make sure to blow away our mLoadingURI just in case. No loads // from inside this pagehide. mLoadingURI = nullptr; - + // Stop any in-progress loading, so that we don't accidentally trigger any // PageShow notifications from Embed() interrupting our loading below. Stop(); @@ -8825,7 +8825,7 @@ nsDocShell::CreateContentViewer(const char *aContentType, } NS_ASSERTION(!mLoadingURI, "Re-entering unload?"); - + nsCOMPtr aOpenedChannel = do_QueryInterface(request); if (aOpenedChannel) { aOpenedChannel->GetURI(getter_AddRefs(mLoadingURI)); @@ -8844,7 +8844,7 @@ nsDocShell::CreateContentViewer(const char *aContentType, if (mLoadType == LOAD_ERROR_PAGE) { // We need to set the SH entry and our current URI here and not - // at the moment we load the page. We want the same behavior + // at the moment we load the page. We want the same behavior // of Stop() as for a normal page load. See bug 514232 for details. // Revert mLoadType to load type to state the page load failed, @@ -8922,9 +8922,9 @@ nsDocShell::CreateContentViewer(const char *aContentType, // Retarget the document to this loadgroup... // /* First attach the channel to the right loadgroup - * and then remove from the old loadgroup. This + * and then remove from the old loadgroup. This * puts the notifications in the right order and - * we don't null-out mLSHE in OnStateChange() for + * we don't null-out mLSHE in OnStateChange() for * all redirected urls */ aOpenedChannel->SetLoadGroup(mLoadGroup); @@ -8972,7 +8972,7 @@ nsDocShell::CreateContentViewer(const char *aContentType, // performance over normal native event dispatch priorities. if (++gNumberOfDocumentsLoading == 1) { // Hint to favor performance for the plevent notification mechanism. - // We want the pages to load as fast as possible even if its means + // We want the pages to load as fast as possible even if its means // native messages might be starved. FavorPerformanceHint(true); } @@ -8980,7 +8980,7 @@ nsDocShell::CreateContentViewer(const char *aContentType, if (onLocationChangeNeeded) { FireOnLocationChange(this, request, mCurrentURI, 0); } - + return NS_OK; } @@ -9266,7 +9266,7 @@ nsDocShell::CheckLoadingPermissions() //***************************************************************************** // nsDocShell: Site Loading -//***************************************************************************** +//***************************************************************************** namespace { @@ -9489,8 +9489,8 @@ nsDocShell::InternalLoad(nsIURI * aURI, // wyciwyg through docshell is illegal. Disallow such loads. if (aLoadType & LOAD_CMD_NORMAL) { bool isWyciwyg = false; - rv = aURI->SchemeIs("wyciwyg", &isWyciwyg); - if ((isWyciwyg && NS_SUCCEEDED(rv)) || NS_FAILED(rv)) + rv = aURI->SchemeIs("wyciwyg", &isWyciwyg); + if ((isWyciwyg && NS_SUCCEEDED(rv)) || NS_FAILED(rv)) return NS_ERROR_FAILURE; } @@ -9629,7 +9629,7 @@ nsDocShell::InternalLoad(nsIURI * aURI, } while (treeItem); } } - + // // Resolve the window target before going any further... // If the load has been targeted to another DocShell, then transfer the @@ -9640,7 +9640,7 @@ nsDocShell::InternalLoad(nsIURI * aURI, // don't try inheriting an owner from the target window if we came up // with a null owner above. aFlags = aFlags & ~INTERNAL_LOAD_FLAGS_INHERIT_OWNER; - + bool isNewWindow = false; if (!targetDocShell) { // If the docshell's document is sandboxed, only open a new window @@ -9736,7 +9736,7 @@ nsDocShell::InternalLoad(nsIURI * aURI, // // NS_ERROR_NO_CONTENT should not be returned to the // caller... This is an internal error code indicating that - // the URI had no data associated with it - probably a + // the URI had no data associated with it - probably a // helper-app style protocol (ie. mailto://) // rv = NS_OK; @@ -9750,7 +9750,7 @@ nsDocShell::InternalLoad(nsIURI * aURI, // Else we ran out of memory, or were a popup and got blocked, // or something. - + return rv; } @@ -9780,7 +9780,7 @@ nsDocShell::InternalLoad(nsIURI * aURI, if (LOAD_TYPE_HAS_FLAGS(aLoadType, LOAD_FLAGS_REPLACE_HISTORY)) { mLoadType = LOAD_NORMAL_REPLACE; } - + // Do this asynchronously nsCOMPtr ev = new InternalLoadEvent(this, aURI, aReferrer, @@ -9946,7 +9946,7 @@ nsDocShell::InternalLoad(nsIURI * aURI, SetHistoryEntry(&mLSHE, aSHEntry); /* This is a anchor traversal with in the same page. - * call OnNewURI() so that, this traversal will be + * call OnNewURI() so that, this traversal will be * recorded in session and global history. */ nsCOMPtr owner; @@ -9993,7 +9993,7 @@ nsDocShell::InternalLoad(nsIURI * aURI, if (mLSHE) { SetHistoryEntry(&mOSHE, mLSHE); // Save the postData obtained from the previous page - // in to the session history entry created for the + // in to the session history entry created for the // anchor page, so that any history load of the anchor // page will restore the appropriate postData. if (postData) @@ -10092,8 +10092,8 @@ nsDocShell::InternalLoad(nsIURI * aURI, } // mContentViewer->PermitUnload can destroy |this| docShell, which - // causes the next call of CanSavePresentation to crash. - // Hold onto |this| until we return, to prevent a crash from happening. + // causes the next call of CanSavePresentation to crash. + // Hold onto |this| until we return, to prevent a crash from happening. // (bug#331040) nsCOMPtr kungFuDeathGrip(this); @@ -10145,11 +10145,11 @@ nsDocShell::InternalLoad(nsIURI * aURI, // current network activity. if (!bIsJavascript && aFileName.IsVoid()) { // Stop any current network activity. - // Also stop content if this is a zombie doc. otherwise - // the onload will be delayed by other loads initiated in the + // Also stop content if this is a zombie doc. otherwise + // the onload will be delayed by other loads initiated in the // background by the first document that // didn't fully load before the next load was initiated. - // If not a zombie, don't stop content until data + // If not a zombie, don't stop content until data // starts arriving from the new URI... nsCOMPtr zombieViewer; @@ -10164,7 +10164,7 @@ nsDocShell::InternalLoad(nsIURI * aURI, rv = Stop(nsIWebNavigation::STOP_NETWORK); } - if (NS_FAILED(rv)) + if (NS_FAILED(rv)) return rv; } @@ -10610,8 +10610,8 @@ nsDocShell::DoURILoad(nsIURI * aURI, uploadChannel->SetUploadStream(aPostData, EmptyCString(), -1); /* If there is a valid postdata *and* it is a History Load, * set up the cache key on the channel, to retrieve the - * data *only* from the cache. If it is a normal reload, the - * cache is free to go to the server for updated postdata. + * data *only* from the cache. If it is a normal reload, the + * cache is free to go to the server for updated postdata. */ if (cacheChannel && cacheKey) { if (mLoadType == LOAD_HISTORY || mLoadType == LOAD_RELOAD_CHARSET_CHANGE) { @@ -10622,7 +10622,7 @@ nsDocShell::DoURILoad(nsIURI * aURI, } else if (mLoadType == LOAD_RELOAD_NORMAL) cacheChannel->SetCacheKey(cacheKey); - } + } } else { /* If there is no postdata, set the cache key on the channel, and @@ -10631,7 +10631,7 @@ nsDocShell::DoURILoad(nsIURI * aURI, * New cache may use it creatively on CGI pages with GET * method and even on those that say "no-cache" */ - if (mLoadType == LOAD_HISTORY || mLoadType == LOAD_RELOAD_NORMAL + if (mLoadType == LOAD_HISTORY || mLoadType == LOAD_RELOAD_NORMAL || mLoadType == LOAD_RELOAD_CHARSET_CHANGE) { if (cacheChannel && cacheKey) cacheChannel->SetCacheKey(cacheKey); @@ -10753,7 +10753,7 @@ nsDocShell::AddHeadersToChannel(nsIInputStream *aHeadersData, // // FINALLY: we can set the header! - // + // rv = httpChannel->SetRequestHeader(headerName, headerValue, true); NS_ENSURE_SUCCESS(rv, rv); @@ -10793,7 +10793,7 @@ nsresult nsDocShell::DoChannelLoad(nsIChannel * aChannel, case LOAD_RELOAD_CHARSET_CHANGE: loadFlags |= nsIRequest::LOAD_FROM_CACHE; break; - + case LOAD_RELOAD_NORMAL: case LOAD_REFRESH: loadFlags |= nsIRequest::VALIDATE_ALWAYS; @@ -10918,7 +10918,7 @@ nsDocShell::ScrollToAnchor(nsACString & aCurHash, nsACString & aNewHash, // Above will fail if the anchor name is not UTF-8. Need to // convert from document charset to unicode. if (NS_FAILED(rv)) { - + // Get a document charset NS_ENSURE_TRUE(mContentViewer, NS_ERROR_FAILURE); nsIDocument* doc = mContentViewer->GetDocument(); @@ -10953,9 +10953,9 @@ nsDocShell::ScrollToAnchor(nsACString & aCurHash, nsACString & aNewHash, // Tell the shell it's at an anchor, without scrolling. shell->GoToAnchor(EmptyString(), false); - + // An empty anchor was found, but if it's a load from history, - // we don't have to jump to the top of the page. Scrollbar + // we don't have to jump to the top of the page. Scrollbar // position will be restored by the caller, based on positions // stored in session history. if (aLoadType == LOAD_HISTORY || aLoadType == LOAD_RELOAD_NORMAL) @@ -11053,7 +11053,7 @@ nsDocShell::OnNewURI(nsIURI * aURI, nsIChannel * aChannel, nsISupports* aOwner, */ nsCOMPtr rootSH = mSessionHistory; if (!rootSH) { - // Get the handle to SH from the root docshell + // Get the handle to SH from the root docshell GetRootSessionHistory(getter_AddRefs(rootSH)); if (!rootSH) { updateSHistory = false; @@ -11093,10 +11093,10 @@ nsDocShell::OnNewURI(nsIURI * aURI, nsIChannel * aChannel, nsISupports* aOwner, * (asserted above) and we should let the normal load continue, * since there's nothing to replace. * - * XXX Hopefully changing the loadType at this time will not hurt + * XXX Hopefully changing the loadType at this time will not hurt * anywhere. The other way to take care of sequentially repeating * frameset pages is to add new methods to nsIDocShellTreeItem. - * Hopefully I don't have to do that. + * Hopefully I don't have to do that. */ if (equalUri && mOSHE && @@ -11115,7 +11115,7 @@ nsDocShell::OnNewURI(nsIURI * aURI, nsIChannel * aChannel, nsISupports* aOwner, } /* If the user pressed shift-reload, cache will create a new cache key - * for the page. Save the new cacheKey in Session History. + * for the page. Save the new cacheKey in Session History. * see bug 90098 */ if (aChannel && @@ -11126,7 +11126,7 @@ nsDocShell::OnNewURI(nsIURI * aURI, nsIChannel * aChannel, nsISupports* aOwner, NS_ASSERTION(!updateSHistory, "We shouldn't be updating session history for forced" " reloads!"); - + nsCOMPtr cacheChannel(do_QueryInterface(aChannel)); nsCOMPtr cacheKey; // Get the Cache Key and store it in SH. @@ -11163,7 +11163,7 @@ nsDocShell::OnNewURI(nsIURI * aURI, nsIChannel * aChannel, nsISupports* aOwner, ClearFrameHistory(mOSHE); } - if (updateSHistory) { + if (updateSHistory) { // Update session history if necessary... if (!mLSHE && (mItemType == typeContent) && mURIResultedInDocument) { /* This is a fresh page getting loaded for the first time @@ -11178,7 +11178,7 @@ nsDocShell::OnNewURI(nsIURI * aURI, nsIChannel * aChannel, nsISupports* aOwner, // If this is a POST request, we do not want to include this in global // history. if (updateGHistory && - aAddToGlobalHistory && + aAddToGlobalHistory && !ChannelIsPost(aChannel)) { nsCOMPtr previousURI; uint32_t previousFlags = 0; @@ -11201,7 +11201,7 @@ nsDocShell::OnNewURI(nsIURI * aURI, nsIChannel * aChannel, nsISupports* aOwner, } // If this was a history load or a refresh, - // update the index in SH. + // update the index in SH. if (rootSH && (mLoadType & (LOAD_CMD_HISTORY | LOAD_CMD_RELOAD))) { nsCOMPtr shInternal(do_QueryInterface(rootSH)); if (shInternal) { @@ -11648,9 +11648,9 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI, nsIChannel * aChannel, shouldPersist = ShouldAddToSessionHistory(aURI); - // Get a handle to the root docshell + // Get a handle to the root docshell nsCOMPtr root; - GetSameTypeRootTreeItem(getter_AddRefs(root)); + GetSameTypeRootTreeItem(getter_AddRefs(root)); /* * If this is a LOAD_FLAGS_REPLACE_HISTORY in a subframe, we use * the existing SH entry in the page and replace the url and @@ -11658,13 +11658,13 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI, nsIChannel * aChannel, */ if (LOAD_TYPE_HAS_FLAGS(mLoadType, LOAD_FLAGS_REPLACE_HISTORY) && root != static_cast(this)) { - // This is a subframe + // This is a subframe entry = mOSHE; nsCOMPtr shContainer(do_QueryInterface(entry)); if (shContainer) { int32_t childCount = 0; shContainer->GetChildCount(&childCount); - // Remove all children of this entry + // Remove all children of this entry for (int32_t i = childCount - 1; i >= 0; i--) { nsCOMPtr child; shContainer->GetChildAt(i, getter_AddRefs(child)); @@ -11702,7 +11702,7 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI, nsIChannel * aChannel, cacheChannel->GetCacheKey(getter_AddRefs(cacheKey)); } nsCOMPtr httpChannel(do_QueryInterface(aChannel)); - + // Check if the httpChannel is hiding under a multipartChannel if (!httpChannel) { GetHttpChannel(aChannel, getter_AddRefs(httpChannel)); @@ -11763,7 +11763,7 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI, nsIChannel * aChannel, /* If cache got a 'no-store', ask SH not to store * HistoryLayoutState. By default, SH will set this * flag to true and save HistoryLayoutState. - */ + */ if (discardLayoutState) { entry->SetSaveLayoutStateFlag(false); } @@ -11791,14 +11791,14 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI, nsIChannel * aChannel, } // This is the root docshell - if (LOAD_TYPE_HAS_FLAGS(mLoadType, LOAD_FLAGS_REPLACE_HISTORY)) { + if (LOAD_TYPE_HAS_FLAGS(mLoadType, LOAD_FLAGS_REPLACE_HISTORY)) { // Replace current entry in session history. - int32_t index = 0; + int32_t index = 0; mSessionHistory->GetIndex(&index); nsCOMPtr shPrivate(do_QueryInterface(mSessionHistory)); // Replace the current entry with the new entry if (shPrivate) - rv = shPrivate->ReplaceEntry(index, entry); + rv = shPrivate->ReplaceEntry(index, entry); } else { // Add to session history @@ -11814,7 +11814,7 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI, nsIChannel * aChannel, #endif } } - else { + else { // This is a subframe. if (!mOSHE || !LOAD_TYPE_HAS_FLAGS(mLoadType, LOAD_FLAGS_REPLACE_HISTORY)) @@ -11840,7 +11840,7 @@ nsDocShell::LoadHistoryEntry(nsISHEntry * aEntry, uint32_t aLoadType) if (!IsNavigationAllowed()) { return NS_OK; } - + nsCOMPtr uri; nsCOMPtr postData; nsCOMPtr referrerURI; @@ -11896,7 +11896,7 @@ nsDocShell::LoadHistoryEntry(nsISHEntry * aEntry, uint32_t aLoadType) } /* If there is a valid postdata *and* the user pressed - * reload or shift-reload, take user's permission before we + * reload or shift-reload, take user's permission before we * repost the data to the server. */ if ((aLoadType & LOAD_CMD_RELOAD) && postData) { @@ -11966,7 +11966,7 @@ nsresult nsDocShell::PersistLayoutHistoryState() { nsresult rv = NS_OK; - + if (mOSHE) { nsCOMPtr shell = GetPresShell(); if (shell) { @@ -12060,7 +12060,7 @@ nsDocShell::CloneAndReplaceChild(nsISHEntry *aEntry, nsDocShell *aShell, } return NS_OK; } - + uint32_t srcID; aEntry->GetID(&srcID); @@ -12283,14 +12283,14 @@ nsDocShell::GetHttpChannel(nsIChannel * aChannel, nsIHttpChannel ** aReturn) return NS_OK; } -bool +bool nsDocShell::ShouldDiscardLayoutState(nsIHttpChannel * aChannel) -{ - // By default layout State will be saved. +{ + // By default layout State will be saved. if (!aChannel) return false; - // figure out if SH should be saving layout state + // figure out if SH should be saving layout state nsCOMPtr securityInfo; bool noStore = false, noCache = false; aChannel->GetSecurityInfo(getter_AddRefs(securityInfo)); @@ -12332,7 +12332,7 @@ NS_IMETHODIMP nsDocShell::GetEditable(bool *aEditable) NS_IMETHODIMP nsDocShell::GetHasEditingSession(bool *aHasEditingSession) { NS_ENSURE_ARG_POINTER(aHasEditingSession); - + if (mEditorData) { nsCOMPtr editingSession; @@ -12703,7 +12703,7 @@ NS_IMETHODIMP nsDocShell::EnsureFind() mFind = do_CreateInstance("@mozilla.org/embedcomp/find;1", &rv); if (NS_FAILED(rv)) return rv; } - + // we promise that the nsIWebBrowserFind that we return has been set // up to point to the focused, or content window, so we have to // set that up each time. @@ -12718,12 +12718,12 @@ NS_IMETHODIMP nsDocShell::EnsureFind() nsCOMPtr findInFrames = do_QueryInterface(mFind); if (!findInFrames) return NS_ERROR_NO_INTERFACE; - + rv = findInFrames->SetRootSearchFrame(ourWindow); if (NS_FAILED(rv)) return rv; rv = findInFrames->SetCurrentSearchFrame(windowToSearch); if (NS_FAILED(rv)) return rv; - + return NS_OK; } @@ -12736,7 +12736,7 @@ nsDocShell::IsFrame() } /* boolean IsBeingDestroyed (); */ -NS_IMETHODIMP +NS_IMETHODIMP nsDocShell::IsBeingDestroyed(bool *aDoomed) { NS_ENSURE_ARG(aDoomed); @@ -12745,7 +12745,7 @@ nsDocShell::IsBeingDestroyed(bool *aDoomed) } -NS_IMETHODIMP +NS_IMETHODIMP nsDocShell::GetIsExecutingOnLoadHandler(bool *aResult) { NS_ENSURE_ARG(aResult); @@ -12784,7 +12784,7 @@ nsRefreshTimer::~nsRefreshTimer() //***************************************************************************** // nsRefreshTimer::nsISupports -//***************************************************************************** +//***************************************************************************** NS_IMPL_ADDREF(nsRefreshTimer) NS_IMPL_RELEASE(nsRefreshTimer) @@ -12820,15 +12820,15 @@ nsDocShell::InterfaceRequestorProxy::InterfaceRequestorProxy(nsIInterfaceRequest mWeakPtr = do_GetWeakReference(p); } } - + nsDocShell::InterfaceRequestorProxy::~InterfaceRequestorProxy() { mWeakPtr = nullptr; } -NS_IMPL_ISUPPORTS(nsDocShell::InterfaceRequestorProxy, nsIInterfaceRequestor) - -NS_IMETHODIMP +NS_IMPL_ISUPPORTS(nsDocShell::InterfaceRequestorProxy, nsIInterfaceRequestor) + +NS_IMETHODIMP nsDocShell::InterfaceRequestorProxy::GetInterface(const nsIID & aIID, void **aSink) { NS_ENSURE_ARG_POINTER(aSink); @@ -12974,7 +12974,7 @@ bool nsDocShell::IsOKToLoadURI(nsIURI* aURI) { NS_PRECONDITION(aURI, "Must have a URI!"); - + if (!mFiredUnloadEvent) { return true; } @@ -13015,12 +13015,12 @@ nsDocShell::IsCommandEnabled(const char * inCommand, bool* outEnabled) *outEnabled = false; nsresult rv = NS_ERROR_FAILURE; - + nsCOMPtr controller; rv = GetControllerForCommand (inCommand, getter_AddRefs(controller)); if (controller) rv = controller->IsCommandEnabled(inCommand, outEnabled); - + return rv; } @@ -13028,12 +13028,12 @@ NS_IMETHODIMP nsDocShell::DoCommand(const char * inCommand) { nsresult rv = NS_ERROR_FAILURE; - + nsCOMPtr controller; rv = GetControllerForCommand(inCommand, getter_AddRefs(controller)); if (controller) rv = controller->DoCommand(inCommand); - + return rv; } @@ -13045,13 +13045,13 @@ nsDocShell::EnsureCommandHandler() nsCOMPtr commandUpdater = do_CreateInstance("@mozilla.org/embedcomp/command-manager;1"); if (!commandUpdater) return NS_ERROR_OUT_OF_MEMORY; - + nsCOMPtr domWindow = GetWindow(); nsresult rv = commandUpdater->Init(domWindow); if (NS_SUCCEEDED(rv)) mCommandManager = do_QueryInterface(commandUpdater); } - + return mCommandManager ? NS_OK : NS_ERROR_FAILURE; } @@ -13247,12 +13247,12 @@ nsDocShell::OnLinkClick(nsIContent* aContent, rv = browserChrome3->OnBeforeLinkTraversal(oldTarget, aURI, linkNode, mIsAppTab, target); } - + if (NS_FAILED(rv)) - target = aTargetSpec; + target = aTargetSpec; nsCOMPtr ev = - new OnLinkClickEvent(this, aContent, aURI, target.get(), aFileName, + new OnLinkClickEvent(this, aContent, aURI, target.get(), aFileName, aPostDataStream, aHeadersDataStream, aIsTrusted); return NS_DispatchToCurrentThread(ev); } @@ -13303,7 +13303,7 @@ nsDocShell::OnLinkClickSync(nsIContent *aContent, bool isExposed; nsresult rv = extProtService->IsExposedProtocol(scheme.get(), &isExposed); if (NS_SUCCEEDED(rv) && !isExposed) { - return extProtService->LoadURI(aURI, this); + return extProtService->LoadURI(aURI, this); } } } @@ -13430,7 +13430,7 @@ nsDocShell::OnOverLink(nsIContent* aContent, NS_ENSURE_SUCCESS(rv, rv); nsAutoString uStr; - rv = textToSubURI->UnEscapeURIForUI(charset, spec, uStr); + rv = textToSubURI->UnEscapeURIForUI(charset, spec, uStr); NS_ENSURE_SUCCESS(rv, rv); mozilla::net::PredictorPredict(aURI, mCurrentURI, @@ -13474,7 +13474,7 @@ nsDocShell::ShouldBlockLoadingForBackButton() return canGoForward; } -bool +bool nsDocShell::PluginsAllowedInCurrentDoc() { bool pluginsAllowed = false; @@ -13482,12 +13482,12 @@ nsDocShell::PluginsAllowedInCurrentDoc() if (!mContentViewer) { return false; } - + nsIDocument* doc = mContentViewer->GetDocument(); if (!doc) { return false; } - + doc->GetAllowPlugins(&pluginsAllowed); return pluginsAllowed; } @@ -13495,7 +13495,7 @@ nsDocShell::PluginsAllowedInCurrentDoc() //---------------------------------------------------------------------- // Web Shell Services API -//This functions is only called when a new charset is detected in loading a document. +//This functions is only called when a new charset is detected in loading a document. //Its name should be changed to "CharsetReloadDocument" NS_IMETHODIMP nsDocShell::ReloadDocument(const char* aCharset, @@ -13526,7 +13526,7 @@ nsDocShell::ReloadDocument(const char* aCharset, NS_IMETHODIMP nsDocShell::StopDocumentLoad(void) { - if(eCharsetReloadRequested != mCharsetReloadState) + if(eCharsetReloadRequested != mCharsetReloadState) { Stop(nsIWebNavigation::STOP_ALL); return NS_OK; diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index ecee5ee54a92..7fd6d8823eff 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -118,7 +118,7 @@ public: int32_t mDelay; bool mRepeat; bool mMetaRefresh; - + protected: virtual ~nsRefreshTimer(); }; @@ -283,15 +283,15 @@ protected: nsresult CreateAboutBlankContentViewer(nsIPrincipal* aPrincipal, nsIURI* aBaseURI, bool aTryToSaveOldPresentation = true); - nsresult CreateContentViewer(const char * aContentType, + nsresult CreateContentViewer(const char * aContentType, nsIRequest * request, nsIStreamListener ** aContentHandler); - nsresult NewContentViewerObj(const char * aContentType, - nsIRequest * request, nsILoadGroup * aLoadGroup, + nsresult NewContentViewerObj(const char * aContentType, + nsIRequest * request, nsILoadGroup * aLoadGroup, nsIStreamListener ** aContentHandler, nsIContentViewer ** aViewer); nsresult SetupNewViewer(nsIContentViewer * aNewViewer); void SetupReferrerFromChannel(nsIChannel * aChannel); - + nsresult GetEldestPresContext(nsPresContext** aPresContext); // Get the principal that we'll set on the channel if we're inheriting. If @@ -325,7 +325,7 @@ protected: const nsAString &aSrcdoc, nsIURI * baseURI, nsContentPolicyType aContentPolicyType); - nsresult AddHeadersToChannel(nsIInputStream * aHeadersData, + nsresult AddHeadersToChannel(nsIInputStream * aHeadersData, nsIChannel * aChannel); nsresult DoChannelLoad(nsIChannel * aChannel, nsIURILoader * aURILoader, @@ -650,12 +650,12 @@ protected: // Method to get our current position and size without flushing void DoGetPositionAndSize(int32_t * x, int32_t * y, int32_t * cx, int32_t * cy); - + // Call this when a URI load is handed to us (via OnLinkClick or // InternalLoad). This makes sure that we're not inside unload, or that if // we are it's still OK to load this URI. bool IsOKToLoadURI(nsIURI* aURI); - + void ReattachEditorToWindow(nsISHEntry *aSHEntry); nsCOMPtr mSessionStorageManager; @@ -916,7 +916,7 @@ protected: // presentation of the page, and to SetupNewViewer() that the old viewer // should be passed a SHEntry to save itself into. bool mSavingOldViewer; - + // @see nsIDocShellHistory::createdDynamically bool mDynamicallyCreated; #ifdef DEBUG @@ -998,7 +998,7 @@ public: explicit InterfaceRequestorProxy(nsIInterfaceRequestor* p); NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIINTERFACEREQUESTOR - + protected: virtual ~InterfaceRequestorProxy(); InterfaceRequestorProxy() {} From 1430792c6b66756569d5e1a41cfc9985c26c5ae2 Mon Sep 17 00:00:00 2001 From: Andrew McCreight Date: Wed, 4 Feb 2015 15:15:13 -0800 Subject: [PATCH 45/74] Bug 1129015, part 2 - Remove trailing whitespace from docloader. r=smaug --- uriloader/base/nsDocLoader.cpp | 102 ++++++++++++++++----------------- uriloader/base/nsDocLoader.h | 18 +++--- 2 files changed, 60 insertions(+), 60 deletions(-) diff --git a/uriloader/base/nsDocLoader.cpp b/uriloader/base/nsDocLoader.cpp index 3e6252beaa8a..f139a9aa68eb 100644 --- a/uriloader/base/nsDocLoader.cpp +++ b/uriloader/base/nsDocLoader.cpp @@ -125,7 +125,7 @@ nsDocLoader::nsDocLoader() ClearInternalProgress(); - PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, + PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, ("DocLoader:%p: created.\n", this)); } @@ -133,7 +133,7 @@ nsresult nsDocLoader::SetDocLoaderParent(nsDocLoader *aParent) { mParent = aParent; - return NS_OK; + return NS_OK; } nsresult @@ -146,7 +146,7 @@ nsDocLoader::Init() nsresult rv = NS_NewLoadGroup(getter_AddRefs(mLoadGroup), this); if (NS_FAILED(rv)) return rv; - PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, + PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, ("DocLoader:%p: load group %x.\n", this, mLoadGroup.get())); return NS_OK; @@ -190,7 +190,7 @@ NS_INTERFACE_MAP_BEGIN(nsDocLoader) NS_INTERFACE_MAP_ENTRY(nsIDocumentLoader) NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) NS_INTERFACE_MAP_ENTRY(nsIWebProgress) - NS_INTERFACE_MAP_ENTRY(nsIProgressEventSink) + NS_INTERFACE_MAP_ENTRY(nsIProgressEventSink) NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor) NS_INTERFACE_MAP_ENTRY(nsIChannelEventSink) NS_INTERFACE_MAP_ENTRY(nsISecurityEventSink) @@ -249,7 +249,7 @@ nsDocLoader::Stop(void) { nsresult rv = NS_OK; - PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, + PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, ("DocLoader:%p: Stop() called\n", this)); NS_OBSERVER_ARRAY_NOTIFY_XPCOM_OBSERVERS(mChildList, nsDocLoader, Stop, ()); @@ -279,9 +279,9 @@ nsDocLoader::Stop(void) NS_ASSERTION(!IsBusy(), "Shouldn't be busy here"); DocLoaderIsEmpty(false); - + return rv; -} +} bool @@ -307,7 +307,7 @@ nsDocLoader::IsBusy() if (!mIsLoadingDocument) { return false; } - + bool busy; rv = mLoadGroup->IsPending(&busy); if (NS_FAILED(rv)) { @@ -359,7 +359,7 @@ nsDocLoader::Destroy() Stop(); // Remove the document loader from the parent list of loaders... - if (mParent) + if (mParent) { mParent->RemoveChildLoader(this); } @@ -453,7 +453,7 @@ nsDocLoader::OnStartRequest(nsIRequest *request, nsISupports *aCtxt) // This request is associated with the entire document... mDocumentRequest = request; - mLoadGroup->SetDefaultLoadRequest(request); + mLoadGroup->SetDefaultLoadRequest(request); // Only fire the start document load notification for the first // document URI... Do not fire it again for redirections @@ -466,7 +466,7 @@ nsDocLoader::OnStartRequest(nsIRequest *request, nsISupports *aCtxt) doStartDocumentLoad(); return NS_OK; } - } + } } NS_ASSERTION(!mIsLoadingDocument || mDocumentRequest, @@ -478,7 +478,7 @@ nsDocLoader::OnStartRequest(nsIRequest *request, nsISupports *aCtxt) } NS_IMETHODIMP -nsDocLoader::OnStopRequest(nsIRequest *aRequest, +nsDocLoader::OnStopRequest(nsIRequest *aRequest, nsISupports *aCtxt, nsresult aStatus) { @@ -519,7 +519,7 @@ nsDocLoader::OnStopRequest(nsIRequest *aRequest, int64_t oldMax = info->mMaxProgress; info->mMaxProgress = info->mCurrentProgress; - + // // If a request whose content-length was previously unknown has just // finished loading, then use this new data to try to calculate a @@ -533,7 +533,7 @@ nsDocLoader::OnStopRequest(nsIRequest *aRequest, // of CalculateMaxProgress() result. We need to remove the info from the // hash, see bug 480713. mCompletedTotalProgress += info->mMaxProgress; - + // // Determine whether a STATE_TRANSFERRING notification should be // 'synthesized'. @@ -587,7 +587,7 @@ nsDocLoader::OnStopRequest(nsIRequest *aRequest, if (bFireTransferring) { // Send a STATE_TRANSFERRING notification for the request. int32_t flags; - + flags = nsIWebProgressListener::STATE_TRANSFERRING | nsIWebProgressListener::STATE_IS_REQUEST; // @@ -607,11 +607,11 @@ nsDocLoader::OnStopRequest(nsIRequest *aRequest, // Fire the OnStateChange(...) notification for stop request // doStopURLLoad(aRequest, aStatus); - + // Clear this request out of the hash to avoid bypass of FireOnStateChange // when address of the request is reused. RemoveRequestInfo(aRequest); - + // // Only fire the DocLoaderIsEmpty(...) if the document loader has initiated a // load. This will handle removing the request from our hashtable as needed. @@ -619,7 +619,7 @@ nsDocLoader::OnStopRequest(nsIRequest *aRequest, if (mIsLoadingDocument) { DocLoaderIsEmpty(true); } - + return NS_OK; } @@ -648,7 +648,7 @@ NS_IMETHODIMP nsDocLoader::GetDocumentChannel(nsIChannel ** aChannel) *aChannel = nullptr; return NS_OK; } - + return CallQueryInterface(mDocumentRequest, aChannel); } @@ -699,7 +699,7 @@ void nsDocLoader::DocLoaderIsEmpty(bool aFlushLayout) // we don't need it anymore to CalculateMaxProgress(). ClearInternalProgress(); - PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, + PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, ("DocLoader:%p: Is now idle...\n", this)); nsCOMPtr docRequest = mDocumentRequest; @@ -712,14 +712,14 @@ void nsDocLoader::DocLoaderIsEmpty(bool aFlushLayout) mProgressStateFlags = nsIWebProgressListener::STATE_STOP; - nsresult loadGroupStatus = NS_OK; + nsresult loadGroupStatus = NS_OK; mLoadGroup->GetStatus(&loadGroupStatus); - // - // New code to break the circular reference between - // the load group and the docloader... - // - mLoadGroup->SetDefaultLoadRequest(nullptr); + // + // New code to break the circular reference between + // the load group and the docloader... + // + mLoadGroup->SetDefaultLoadRequest(nullptr); // Take a ref to our parent now so that we can call DocLoaderIsEmpty() on // it even if our onload handler removes us from the docloader tree. @@ -750,7 +750,7 @@ void nsDocLoader::doStartDocumentLoad(void) nsAutoCString buffer; GetURIStringFromRequest(mDocumentRequest, buffer); - PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, + PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, ("DocLoader:%p: ++ Firing OnStateChange for start document load (...)." "\tURI: %s \n", this, buffer.get())); @@ -775,7 +775,7 @@ void nsDocLoader::doStartURLLoad(nsIRequest *request) nsAutoCString buffer; GetURIStringFromRequest(request, buffer); - PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, + PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, ("DocLoader:%p: ++ Firing OnStateChange start url load (...)." "\tURI: %s\n", this, buffer.get())); @@ -794,7 +794,7 @@ void nsDocLoader::doStopURLLoad(nsIRequest *request, nsresult aStatus) nsAutoCString buffer; GetURIStringFromRequest(request, buffer); - PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, + PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, ("DocLoader:%p: ++ Firing OnStateChange for end url load (...)." "\tURI: %s status=%x\n", this, buffer.get(), aStatus)); @@ -823,7 +823,7 @@ void nsDocLoader::doStopDocumentLoad(nsIRequest *request, nsAutoCString buffer; GetURIStringFromRequest(request, buffer); - PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, + PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, ("DocLoader:%p: ++ Firing OnStateChange for end document load (...)." "\tURI: %s Status=%x\n", this, buffer.get(), aStatus)); @@ -835,7 +835,7 @@ void nsDocLoader::doStopDocumentLoad(nsIRequest *request, // the onload handlers rearrange the docshell tree. WebProgressList list; GatherAncestorWebProgresses(list); - + // // Fire an OnStateChange(...) notification indicating the the // current document has finished loading... @@ -952,7 +952,7 @@ int64_t nsDocLoader::GetMaxTotalProgress() uint32_t count = mChildList.Length(); nsCOMPtr webProgress; - for (uint32_t i=0; i < count; i++) + for (uint32_t i=0; i < count; i++) { int64_t individualProgress = 0; nsIDocumentLoader* docloader = ChildAt(i); @@ -974,17 +974,17 @@ int64_t nsDocLoader::GetMaxTotalProgress() int64_t progress = -1; if (mMaxSelfProgress >= int64_t(0) && newMaxTotal >= int64_t(0)) progress = newMaxTotal + mMaxSelfProgress; - + return progress; } //////////////////////////////////////////////////////////////////////////////////// -// The following section contains support for nsIProgressEventSink which is used to +// The following section contains support for nsIProgressEventSink which is used to // pass progress and status between the actual request and the doc loader. The doc loader // then turns around and makes the right web progress calls based on this information. //////////////////////////////////////////////////////////////////////////////////// -NS_IMETHODIMP nsDocLoader::OnProgress(nsIRequest *aRequest, nsISupports* ctxt, +NS_IMETHODIMP nsDocLoader::OnProgress(nsIRequest *aRequest, nsISupports* ctxt, int64_t aProgress, int64_t aProgressMax) { int64_t progressDelta = 0; @@ -1010,7 +1010,7 @@ NS_IMETHODIMP nsDocLoader::OnProgress(nsIRequest *aRequest, nsISupports* ctxt, nsLoadFlags lf = 0; aRequest->GetLoadFlags(&lf); if ((lf & nsIChannel::LOAD_DOCUMENT_URI) && !(lf & nsIChannel::LOAD_TARGETED)) { - PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, + PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, ("DocLoader:%p Ignoring OnProgress while load is not targeted\n", this)); return NS_OK; } @@ -1031,8 +1031,8 @@ NS_IMETHODIMP nsDocLoader::OnProgress(nsIRequest *aRequest, nsISupports* ctxt, // Send a STATE_TRANSFERRING notification for the request. int32_t flags; - - flags = nsIWebProgressListener::STATE_TRANSFERRING | + + flags = nsIWebProgressListener::STATE_TRANSFERRING | nsIWebProgressListener::STATE_IS_REQUEST; // // Move the WebProgress into the STATE_TRANSFERRING state if necessary... @@ -1059,7 +1059,7 @@ NS_IMETHODIMP nsDocLoader::OnProgress(nsIRequest *aRequest, nsISupports* ctxt, nsAutoCString buffer; GetURIStringFromRequest(aRequest, buffer); - PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, + PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, ("DocLoader:%p OOPS - No Request Info for: %s\n", this, buffer.get())); #endif /* DEBUG */ @@ -1076,7 +1076,7 @@ NS_IMETHODIMP nsDocLoader::OnProgress(nsIRequest *aRequest, nsISupports* ctxt, return NS_OK; } -NS_IMETHODIMP nsDocLoader::OnStatus(nsIRequest* aRequest, nsISupports* ctxt, +NS_IMETHODIMP nsDocLoader::OnStatus(nsIRequest* aRequest, nsISupports* ctxt, nsresult aStatus, const char16_t* aStatusArg) { // @@ -1189,7 +1189,7 @@ void nsDocLoader::FireOnProgressChange(nsDocLoader *aLoadInitiator, nsAutoCString buffer; GetURIStringFromRequest(request, buffer); - PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, + PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, ("DocLoader:%p: Progress (%s): curSelf: %d maxSelf: %d curTotal: %d maxTotal %d\n", this, buffer.get(), aProgress, aProgressMax, aTotalProgress, aMaxTotalProgress)); #endif /* DEBUG */ @@ -1242,7 +1242,7 @@ void nsDocLoader::DoFireOnStateChange(nsIWebProgress * const aProgress, // active... // if (mIsLoadingDocument && - (aStateFlags & nsIWebProgressListener::STATE_IS_NETWORK) && + (aStateFlags & nsIWebProgressListener::STATE_IS_NETWORK) && (this != aProgress)) { aStateFlags &= ~nsIWebProgressListener::STATE_IS_NETWORK; } @@ -1255,7 +1255,7 @@ void nsDocLoader::DoFireOnStateChange(nsIWebProgress * const aProgress, nsAutoCString buffer; GetURIStringFromRequest(aRequest, buffer); - PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, + PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, ("DocLoader:%p: Status (%s): code: %x\n", this, buffer.get(), aStateFlags)); #endif /* DEBUG */ @@ -1295,7 +1295,7 @@ nsDocLoader::FireOnStatusChange(nsIWebProgress* aWebProgress, NOTIFY_LISTENERS(nsIWebProgress::NOTIFY_STATUS, listener->OnStatusChange(aWebProgress, aRequest, aStatus, aMessage); ); - + // Pass the notification up to the parent... if (mParent) { mParent->FireOnStatusChange(aWebProgress, aRequest, aStatus, aMessage); @@ -1444,9 +1444,9 @@ NS_IMETHODIMP nsDocLoader::OnSecurityChange(nsISupports * aContext, uint32_t aState) { // - // Fire progress notifications out to any registered nsIWebProgressListeners. + // Fire progress notifications out to any registered nsIWebProgressListeners. // - + nsCOMPtr request = do_QueryInterface(aContext); nsIWebProgress* webProgress = static_cast(this); @@ -1467,7 +1467,7 @@ NS_IMETHODIMP nsDocLoader::OnSecurityChange(nsISupports * aContext, * The priority of the DocLoader _is_ the priority of its LoadGroup. * * XXX(darin): Once we start storing loadgroups in loadgroups, this code will - * go away. + * go away. */ NS_IMETHODIMP nsDocLoader::GetPriority(int32_t *aPriority) @@ -1482,7 +1482,7 @@ NS_IMETHODIMP nsDocLoader::GetPriority(int32_t *aPriority) NS_IMETHODIMP nsDocLoader::SetPriority(int32_t aPriority) { - PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, + PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, ("DocLoader:%p: SetPriority(%d) called\n", this, aPriority)); nsCOMPtr p = do_QueryInterface(mLoadGroup); @@ -1497,7 +1497,7 @@ NS_IMETHODIMP nsDocLoader::SetPriority(int32_t aPriority) NS_IMETHODIMP nsDocLoader::AdjustPriority(int32_t aDelta) { - PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, + PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, ("DocLoader:%p: AdjustPriority(%d) called\n", this, aDelta)); nsCOMPtr p = do_QueryInterface(mLoadGroup); @@ -1520,7 +1520,7 @@ void nsDocLoader::DumpChannelInfo() int32_t i, count; int32_t current=0, max=0; - + printf("==== DocLoader=%x\n", this); count = mChannelInfoList.Count(); @@ -1535,7 +1535,7 @@ void nsDocLoader::DumpChannelInfo() } printf(" [%d] current=%d max=%d [%s]\n", i, - info->mCurrentProgress, + info->mCurrentProgress, info->mMaxProgress, buffer.get()); #endif /* DEBUG */ diff --git a/uriloader/base/nsDocLoader.h b/uriloader/base/nsDocLoader.h index 057ae6ddf4c5..a4a0ee0c0da5 100644 --- a/uriloader/base/nsDocLoader.h +++ b/uriloader/base/nsDocLoader.h @@ -3,7 +3,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* +/* */ #ifndef nsDocLoader_h__ @@ -43,7 +43,7 @@ {0x93, 0xb6, 0x6d, 0x23, 0x06, 0x9c, 0x06, 0xf2} \ } -class nsDocLoader : public nsIDocumentLoader, +class nsDocLoader : public nsIDocumentLoader, public nsIRequestObserver, public nsSupportsWeakReference, public nsIProgressEventSink, @@ -71,7 +71,7 @@ public: NS_DECL_ISUPPORTS NS_DECL_NSIDOCUMENTLOADER - + // nsIProgressEventSink NS_DECL_NSIPROGRESSEVENTSINK @@ -96,7 +96,7 @@ public: nsDocLoader* GetParent() const { return mParent; } struct nsListenerInfo { - nsListenerInfo(nsIWeakReference *aListener, unsigned long aNotifyMask) + nsListenerInfo(nsIWeakReference *aListener, unsigned long aNotifyMask) : mWeakListener(aListener), mNotifyMask(aNotifyMask) { @@ -199,7 +199,7 @@ protected: void ChildDoneWithOnload(nsIDocumentLoader* aChild) { mChildrenInOnload.RemoveObject(aChild); DocLoaderIsEmpty(true); - } + } protected: struct nsStatusInfo : public mozilla::LinkedListElement @@ -255,7 +255,7 @@ protected: // for owning pointers and raw COM interface pointers for weak // (ie, non owning) references. If you add any members to this // class, please make the ownership explicit (pinkerton, scc). - + nsCOMPtr mDocumentRequest; // [OWNER] ???compare with document nsDocLoader* mParent; // [WEAK] @@ -267,7 +267,7 @@ protected: // We hold weak refs to all our kids nsTObserverArray mChildList; - // The following member variables are related to the new nsIWebProgress + // The following member variables are related to the new nsIWebProgress // feedback interfaces that travis cooked up. int32_t mProgressStateFlags; @@ -308,7 +308,7 @@ private: // DocLoaderIsEmpty calls (those coming from requests finishing in our // loadgroup) unless this is empty. nsCOMArray mChildrenInOnload; - + // DocLoaderIsEmpty should be called whenever the docloader may be empty. // This method is idempotent and does nothing if the docloader is not in // fact empty. This method _does_ make sure that layout is flushed if our @@ -329,7 +329,7 @@ private: /// void DumpChannelInfo(void); // used to clear our internal progress state between loads... - void ClearInternalProgress(); + void ClearInternalProgress(); }; NS_DEFINE_STATIC_IID_ACCESSOR(nsDocLoader, NS_THIS_DOCLOADER_IMPL_CID) From a271bba5671672d81d391499c1fab22d63b6692b Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Wed, 4 Feb 2015 15:22:27 -0800 Subject: [PATCH 46/74] Bug 1128356 - Add template functions for common frame property destructors. r=dbaron --- layout/base/ActiveLayerTracker.cpp | 7 +-- layout/base/nsDisplayList.h | 9 ++-- layout/forms/nsTextControlFrame.h | 2 +- layout/generic/StickyScrollContainer.cpp | 7 +-- layout/generic/StickyScrollContainer.h | 5 +- layout/generic/nsFloatManager.cpp | 2 +- layout/generic/nsFontInflationData.cpp | 9 +--- layout/generic/nsFrame.cpp | 38 ++------------ layout/generic/nsGridContainerFrame.cpp | 6 --- layout/generic/nsGridContainerFrame.h | 4 +- layout/generic/nsIFrame.h | 64 +++++++++++------------- layout/generic/nsTextFrame.cpp | 15 ++---- layout/mathml/nsMathMLContainerFrame.cpp | 9 +--- layout/mathml/nsMathMLmtableFrame.cpp | 14 ++---- layout/svg/SVGTextFrame.cpp | 8 +-- layout/svg/nsSVGEffects.h | 29 ++++------- layout/tables/nsTableFrame.cpp | 16 +----- layout/tables/nsTableFrame.h | 4 +- layout/tables/nsTableRowGroupFrame.cpp | 9 +--- 19 files changed, 71 insertions(+), 186 deletions(-) diff --git a/layout/base/ActiveLayerTracker.cpp b/layout/base/ActiveLayerTracker.cpp index d0bf4eb7cefa..00fce77fc46b 100644 --- a/layout/base/ActiveLayerTracker.cpp +++ b/layout/base/ActiveLayerTracker.cpp @@ -107,13 +107,8 @@ LayerActivity::~LayerActivity() } } -static void DestroyLayerActivity(void* aPropertyValue) -{ - delete static_cast(aPropertyValue); -} - // Frames with this property have NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY set -NS_DECLARE_FRAME_PROPERTY(LayerActivityProperty, DestroyLayerActivity) +NS_DECLARE_FRAME_PROPERTY(LayerActivityProperty, DeleteValue) void LayerActivityTracker::NotifyExpired(LayerActivity* aObject) diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index 1fca24efb1d0..dc635a8ad546 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -714,13 +714,10 @@ public: DisplayItemClip mContainingBlockClip; nsRect mDirtyRect; }; - static void DestroyOutOfFlowDisplayData(void* aPropertyValue) - { - delete static_cast(aPropertyValue); - } - NS_DECLARE_FRAME_PROPERTY(OutOfFlowDisplayDataProperty, DestroyOutOfFlowDisplayData) - NS_DECLARE_FRAME_PROPERTY(Preserve3DDirtyRectProperty, nsIFrame::DestroyRect) + NS_DECLARE_FRAME_PROPERTY(OutOfFlowDisplayDataProperty, + DeleteValue) + NS_DECLARE_FRAME_PROPERTY(Preserve3DDirtyRectProperty, DeleteValue) nsPresContext* CurrentPresContext() { return CurrentPresShellState()->mPresShell->GetPresContext(); diff --git a/layout/forms/nsTextControlFrame.h b/layout/forms/nsTextControlFrame.h index c8d70d34d13e..587006550efb 100644 --- a/layout/forms/nsTextControlFrame.h +++ b/layout/forms/nsTextControlFrame.h @@ -32,7 +32,7 @@ class nsTextControlFrame MOZ_FINAL : public nsContainerFrame, public: NS_DECL_FRAMEARENA_HELPERS - NS_DECLARE_FRAME_PROPERTY(ContentScrollPos, DestroyPoint) + NS_DECLARE_FRAME_PROPERTY(ContentScrollPos, DeleteValue) explicit nsTextControlFrame(nsStyleContext* aContext); virtual ~nsTextControlFrame(); diff --git a/layout/generic/StickyScrollContainer.cpp b/layout/generic/StickyScrollContainer.cpp index 3b5b60263c2f..285656b4d247 100644 --- a/layout/generic/StickyScrollContainer.cpp +++ b/layout/generic/StickyScrollContainer.cpp @@ -17,13 +17,8 @@ namespace mozilla { -void DestroyStickyScrollContainer(void* aPropertyValue) -{ - delete static_cast(aPropertyValue); -} - NS_DECLARE_FRAME_PROPERTY(StickyScrollContainerProperty, - DestroyStickyScrollContainer) + DeleteValue) StickyScrollContainer::StickyScrollContainer(nsIScrollableFrame* aScrollFrame) : mScrollFrame(aScrollFrame) diff --git a/layout/generic/StickyScrollContainer.h b/layout/generic/StickyScrollContainer.h index eb818d5bc9e5..9cd4c0af9859 100644 --- a/layout/generic/StickyScrollContainer.h +++ b/layout/generic/StickyScrollContainer.h @@ -86,9 +86,10 @@ public: virtual void ScrollPositionWillChange(nscoord aX, nscoord aY) MOZ_OVERRIDE; virtual void ScrollPositionDidChange(nscoord aX, nscoord aY) MOZ_OVERRIDE; + ~StickyScrollContainer(); + private: explicit StickyScrollContainer(nsIScrollableFrame* aScrollFrame); - ~StickyScrollContainer(); /** * Compute two rectangles that determine sticky positioning: |aStick|, based @@ -99,8 +100,6 @@ private: void ComputeStickyLimits(nsIFrame* aFrame, nsRect* aStick, nsRect* aContain) const; - friend void DestroyStickyScrollContainer(void* aPropertyValue); - nsIScrollableFrame* const mScrollFrame; nsTArray mFrames; nsPoint mScrollPosition; diff --git a/layout/generic/nsFloatManager.cpp b/layout/generic/nsFloatManager.cpp index 480914ba00d4..fbe6c0a83487 100644 --- a/layout/generic/nsFloatManager.cpp +++ b/layout/generic/nsFloatManager.cpp @@ -307,7 +307,7 @@ nsFloatManager::CalculateRegionFor(WritingMode aWM, return region; } -NS_DECLARE_FRAME_PROPERTY(FloatRegionProperty, nsIFrame::DestroyMargin) +NS_DECLARE_FRAME_PROPERTY(FloatRegionProperty, DeleteValue) LogicalRect nsFloatManager::GetRegionFor(WritingMode aWM, nsIFrame* aFloat, diff --git a/layout/generic/nsFontInflationData.cpp b/layout/generic/nsFontInflationData.cpp index 0873e1bc7f53..9e33034d19ea 100644 --- a/layout/generic/nsFontInflationData.cpp +++ b/layout/generic/nsFontInflationData.cpp @@ -16,13 +16,8 @@ using namespace mozilla; using namespace mozilla::layout; -static void -DestroyFontInflationData(void *aPropertyValue) -{ - delete static_cast(aPropertyValue); -} - -NS_DECLARE_FRAME_PROPERTY(FontInflationDataProperty, DestroyFontInflationData) +NS_DECLARE_FRAME_PROPERTY(FontInflationDataProperty, + DeleteValue) /* static */ nsFontInflationData* nsFontInflationData::FindFontInflationDataFor(const nsIFrame *aFrame) diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 37656030c33e..785dfe7bed02 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -152,13 +152,7 @@ static void RefreshContentFrames(nsPresContext* aPresContext, nsIContent * aStar #include "prenv.h" -static void -DestroyBoxMetrics(void* aPropertyValue) -{ - delete static_cast(aPropertyValue); -} - -NS_DECLARE_FRAME_PROPERTY(BoxMetricsProperty, DestroyBoxMetrics) +NS_DECLARE_FRAME_PROPERTY(BoxMetricsProperty, DeleteValue) static void InitBoxMetrics(nsIFrame* aFrame, bool aClear) @@ -250,13 +244,8 @@ nsFrame::GetLogModuleInfo() #endif -static void -DestroyAbsoluteContainingBlock(void* aPropertyValue) -{ - delete static_cast(aPropertyValue); -} - -NS_DECLARE_FRAME_PROPERTY(AbsoluteContainingBlockProperty, DestroyAbsoluteContainingBlock) +NS_DECLARE_FRAME_PROPERTY(AbsoluteContainingBlockProperty, + DeleteValue) bool nsIFrame::HasAbsolutelyPositionedChildren() const { @@ -7122,8 +7111,7 @@ nsFrame::AccessibleType() } #endif -NS_DECLARE_FRAME_PROPERTY(OverflowAreasProperty, - nsIFrame::DestroyOverflowAreas) +NS_DECLARE_FRAME_PROPERTY(OverflowAreasProperty, DeleteValue) bool nsIFrame::ClearOverflowRects() @@ -8772,24 +8760,6 @@ nsIFrame::IsSelected() const IsFrameSelected() : false; } -void -nsIFrame::DestroySurface(void* aPropertyValue) -{ - static_cast(aPropertyValue)->Release(); -} - -void -nsIFrame::DestroyDT(void* aPropertyValue) -{ - static_cast(aPropertyValue)->Release(); -} - -void -nsIFrame::DestroyRegion(void* aPropertyValue) -{ - delete static_cast(aPropertyValue); -} - /*static*/ void nsIFrame::DestroyContentArray(void* aPropertyValue) { diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index de1034016840..fb4d9ae05ca3 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -64,12 +64,6 @@ NS_NewGridContainerFrame(nsIPresShell* aPresShell, // nsGridContainerFrame Method Implementations // =========================================== -/* static */ void -nsGridContainerFrame::DestroyImplicitNamedAreas(void* aPropertyValue) -{ - delete static_cast(aPropertyValue); -} - void nsGridContainerFrame::AddImplicitNamedAreas( const nsTArray>& aLineNameLists) diff --git a/layout/generic/nsGridContainerFrame.h b/layout/generic/nsGridContainerFrame.h index aa98ab918f61..aa0e06aa7a94 100644 --- a/layout/generic/nsGridContainerFrame.h +++ b/layout/generic/nsGridContainerFrame.h @@ -49,14 +49,14 @@ protected: * grid-template-columns / grid-template-rows are stored in this frame * property when needed, as a ImplicitNamedAreas* value. */ - NS_DECLARE_FRAME_PROPERTY(ImplicitNamedAreasProperty, DestroyImplicitNamedAreas) + NS_DECLARE_FRAME_PROPERTY(ImplicitNamedAreasProperty, + DeleteValue) void InitImplicitNamedAreas(const nsStylePosition* aStyle); void AddImplicitNamedAreas(const nsTArray>& aLineNameLists); typedef nsTHashtable ImplicitNamedAreas; ImplicitNamedAreas* GetImplicitNamedAreas() const { return static_cast(Properties().Get(ImplicitNamedAreasProperty())); } - static void DestroyImplicitNamedAreas(void* aPropertyValue); #ifdef DEBUG void SanityCheckAnonymousGridItems() const; diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 8273ae77506c..29a54e8580cd 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -367,6 +367,20 @@ struct IntrinsicSize { }; } +/// Generic destructor for frame properties. Calls delete. +template +static void DeleteValue(void* aPropertyValue) +{ + delete static_cast(aPropertyValue); +} + +/// Generic destructor for frame properties. Calls Release(). +template +static void ReleaseValue(void* aPropertyValue) +{ + static_cast(aPropertyValue)->Release(); +} + //---------------------------------------------------------------------- /** @@ -783,30 +797,6 @@ public: nsPoint GetPositionIgnoringScrolling(); - static void DestroyRegion(void* aPropertyValue); - - static void DestroyMargin(void* aPropertyValue) - { - delete static_cast(aPropertyValue); - } - - static void DestroyRect(void* aPropertyValue) - { - delete static_cast(aPropertyValue); - } - - static void DestroyPoint(void* aPropertyValue) - { - delete static_cast(aPropertyValue); - } - - static void DestroyOverflowAreas(void* aPropertyValue) - { - delete static_cast(aPropertyValue); - } - - static void DestroySurface(void* aPropertyValue); - static void DestroyDT(void* aPropertyValue); static void DestroyContentArray(void* aPropertyValue); #ifdef _MSC_VER @@ -832,18 +822,19 @@ public: NS_DECLARE_FRAME_PROPERTY(IBSplitSibling, nullptr) NS_DECLARE_FRAME_PROPERTY(IBSplitPrevSibling, nullptr) - NS_DECLARE_FRAME_PROPERTY(NormalPositionProperty, DestroyPoint) - NS_DECLARE_FRAME_PROPERTY(ComputedOffsetProperty, DestroyMargin) + NS_DECLARE_FRAME_PROPERTY(NormalPositionProperty, DeleteValue) + NS_DECLARE_FRAME_PROPERTY(ComputedOffsetProperty, DeleteValue) - NS_DECLARE_FRAME_PROPERTY(OutlineInnerRectProperty, DestroyRect) - NS_DECLARE_FRAME_PROPERTY(PreEffectsBBoxProperty, DestroyRect) + NS_DECLARE_FRAME_PROPERTY(OutlineInnerRectProperty, DeleteValue) + NS_DECLARE_FRAME_PROPERTY(PreEffectsBBoxProperty, DeleteValue) NS_DECLARE_FRAME_PROPERTY(PreTransformOverflowAreasProperty, - DestroyOverflowAreas) + DeleteValue) // The initial overflow area passed to FinishAndStoreOverflow. This is only set // on frames that Preserve3D() or HasPerspective() or IsTransformed(), and // when at least one of the overflow areas differs from the frame bound rect. - NS_DECLARE_FRAME_PROPERTY(InitialOverflowProperty, DestroyOverflowAreas) + NS_DECLARE_FRAME_PROPERTY(InitialOverflowProperty, + DeleteValue) #ifdef DEBUG // InitialOverflowPropertyDebug is added to the frame to indicate that either @@ -852,18 +843,19 @@ public: NS_DECLARE_FRAME_PROPERTY(DebugInitialOverflowPropertyApplied, nullptr) #endif - NS_DECLARE_FRAME_PROPERTY(UsedMarginProperty, DestroyMargin) - NS_DECLARE_FRAME_PROPERTY(UsedPaddingProperty, DestroyMargin) - NS_DECLARE_FRAME_PROPERTY(UsedBorderProperty, DestroyMargin) + NS_DECLARE_FRAME_PROPERTY(UsedMarginProperty, DeleteValue) + NS_DECLARE_FRAME_PROPERTY(UsedPaddingProperty, DeleteValue) + NS_DECLARE_FRAME_PROPERTY(UsedBorderProperty, DeleteValue) NS_DECLARE_FRAME_PROPERTY(ScrollLayerCount, nullptr) NS_DECLARE_FRAME_PROPERTY(LineBaselineOffset, nullptr) - NS_DECLARE_FRAME_PROPERTY(CachedBackgroundImage, DestroySurface) - NS_DECLARE_FRAME_PROPERTY(CachedBackgroundImageDT, DestroyDT) + NS_DECLARE_FRAME_PROPERTY(CachedBackgroundImage, ReleaseValue) + NS_DECLARE_FRAME_PROPERTY(CachedBackgroundImageDT, + ReleaseValue) - NS_DECLARE_FRAME_PROPERTY(InvalidationRect, DestroyRect) + NS_DECLARE_FRAME_PROPERTY(InvalidationRect, DeleteValue) NS_DECLARE_FRAME_PROPERTY(RefusedAsyncAnimation, nullptr) diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index 497741f16f51..75a10cb0b9be 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -181,12 +181,7 @@ TabWidthStore::ApplySpacing(gfxTextRun::PropertyProvider::Spacing *aSpacing, } } -static void DestroyTabWidth(void* aPropertyValue) -{ - delete static_cast(aPropertyValue); -} - -NS_DECLARE_FRAME_PROPERTY(TabWidthProperty, DestroyTabWidth) +NS_DECLARE_FRAME_PROPERTY(TabWidthProperty, DeleteValue) NS_DECLARE_FRAME_PROPERTY(OffsetToFrameProperty, nullptr) @@ -204,18 +199,14 @@ private: nsTextFrame* mFrame; }; -static void DestroyGlyphObserverList(void* aPropertyValue) -{ - delete static_cast >*>(aPropertyValue); -} - /** * This property is set on text frames with TEXT_IN_TEXTRUN_USER_DATA set that * have potentially-animated glyphs. * The only reason this list is in a property is to automatically destroy the * list when the frame is deleted, unregistering the observers. */ -NS_DECLARE_FRAME_PROPERTY(TextFrameGlyphObservers, DestroyGlyphObserverList); +NS_DECLARE_FRAME_PROPERTY(TextFrameGlyphObservers, + DeleteValue>>); static const nsFrameState TEXT_REFLOW_FLAGS = TEXT_FIRST_LETTER | diff --git a/layout/mathml/nsMathMLContainerFrame.cpp b/layout/mathml/nsMathMLContainerFrame.cpp index efec3ba36a9b..4e6700118730 100644 --- a/layout/mathml/nsMathMLContainerFrame.cpp +++ b/layout/mathml/nsMathMLContainerFrame.cpp @@ -129,13 +129,8 @@ IsForeignChild(const nsIFrame* aFrame) aFrame->GetType() == nsGkAtoms::blockFrame; } -static void -DestroyHTMLReflowMetrics(void *aPropertyValue) -{ - delete static_cast(aPropertyValue); -} - -NS_DECLARE_FRAME_PROPERTY(HTMLReflowMetricsProperty, DestroyHTMLReflowMetrics) +NS_DECLARE_FRAME_PROPERTY(HTMLReflowMetricsProperty, + DeleteValue) /* static */ void nsMathMLContainerFrame::SaveReflowAndBoundingMetricsFor(nsIFrame* aFrame, diff --git a/layout/mathml/nsMathMLmtableFrame.cpp b/layout/mathml/nsMathMLmtableFrame.cpp index 8bb701669e36..c2145d9aa5d9 100644 --- a/layout/mathml/nsMathMLmtableFrame.cpp +++ b/layout/mathml/nsMathMLmtableFrame.cpp @@ -130,16 +130,10 @@ static nsresult ReportParseError(nsIFrame* aFrame, const char16_t* aAttribute, // stored in the property table. Row/Cell frames query the property table // to see what values apply to them. -static void -DestroyStylePropertyList(void* aPropertyValue) -{ - delete static_cast*>(aPropertyValue); -} - -NS_DECLARE_FRAME_PROPERTY(RowAlignProperty, DestroyStylePropertyList) -NS_DECLARE_FRAME_PROPERTY(RowLinesProperty, DestroyStylePropertyList) -NS_DECLARE_FRAME_PROPERTY(ColumnAlignProperty, DestroyStylePropertyList) -NS_DECLARE_FRAME_PROPERTY(ColumnLinesProperty, DestroyStylePropertyList) +NS_DECLARE_FRAME_PROPERTY(RowAlignProperty, DeleteValue>) +NS_DECLARE_FRAME_PROPERTY(RowLinesProperty, DeleteValue>) +NS_DECLARE_FRAME_PROPERTY(ColumnAlignProperty, DeleteValue>) +NS_DECLARE_FRAME_PROPERTY(ColumnLinesProperty, DeleteValue>) static const FramePropertyDescriptor* AttributeToProperty(nsIAtom* aAttribute) diff --git a/layout/svg/SVGTextFrame.cpp b/layout/svg/SVGTextFrame.cpp index cad5f23997ab..31fa9ee3c5d4 100644 --- a/layout/svg/SVGTextFrame.cpp +++ b/layout/svg/SVGTextFrame.cpp @@ -1286,12 +1286,8 @@ struct TextNodeCorrespondence uint32_t mUndisplayedCharacters; }; -static void DestroyTextNodeCorrespondence(void* aPropertyValue) -{ - delete static_cast(aPropertyValue); -} - -NS_DECLARE_FRAME_PROPERTY(TextNodeCorrespondenceProperty, DestroyTextNodeCorrespondence) +NS_DECLARE_FRAME_PROPERTY(TextNodeCorrespondenceProperty, + DeleteValue) /** * Returns the number of undisplayed characters before the specified diff --git a/layout/svg/nsSVGEffects.h b/layout/svg/nsSVGEffects.h index 667a52030422..6c000d1b9f8d 100644 --- a/layout/svg/nsSVGEffects.h +++ b/layout/svg/nsSVGEffects.h @@ -390,11 +390,6 @@ public: typedef nsInterfaceHashtable URIObserverHashtable; - static void DestroySupports(void* aPropertyValue) - { - (static_cast(aPropertyValue))->Release(); - } - static void DestroyFilterProperty(void* aPropertyValue) { auto* prop = static_cast(aPropertyValue); @@ -407,21 +402,17 @@ public: prop->Release(); } - static void DestroyHashtable(void* aPropertyValue) - { - delete static_cast (aPropertyValue); - } - NS_DECLARE_FRAME_PROPERTY(FilterProperty, DestroyFilterProperty) - NS_DECLARE_FRAME_PROPERTY(MaskProperty, DestroySupports) - NS_DECLARE_FRAME_PROPERTY(ClipPathProperty, DestroySupports) - NS_DECLARE_FRAME_PROPERTY(MarkerBeginProperty, DestroySupports) - NS_DECLARE_FRAME_PROPERTY(MarkerMiddleProperty, DestroySupports) - NS_DECLARE_FRAME_PROPERTY(MarkerEndProperty, DestroySupports) - NS_DECLARE_FRAME_PROPERTY(FillProperty, DestroySupports) - NS_DECLARE_FRAME_PROPERTY(StrokeProperty, DestroySupports) - NS_DECLARE_FRAME_PROPERTY(HrefProperty, DestroySupports) - NS_DECLARE_FRAME_PROPERTY(BackgroundImageProperty, DestroyHashtable) + NS_DECLARE_FRAME_PROPERTY(MaskProperty, ReleaseValue) + NS_DECLARE_FRAME_PROPERTY(ClipPathProperty, ReleaseValue) + NS_DECLARE_FRAME_PROPERTY(MarkerBeginProperty, ReleaseValue) + NS_DECLARE_FRAME_PROPERTY(MarkerMiddleProperty, ReleaseValue) + NS_DECLARE_FRAME_PROPERTY(MarkerEndProperty, ReleaseValue) + NS_DECLARE_FRAME_PROPERTY(FillProperty, ReleaseValue) + NS_DECLARE_FRAME_PROPERTY(StrokeProperty, ReleaseValue) + NS_DECLARE_FRAME_PROPERTY(HrefProperty, ReleaseValue) + NS_DECLARE_FRAME_PROPERTY(BackgroundImageProperty, + DeleteValue) /** * Get the paint server for a aTargetFrame. diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index 9a5a3370eb03..a4520ea57444 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -260,13 +260,6 @@ nsTableFrame::PageBreakAfter(nsIFrame* aSourceFrame, typedef nsTArray FrameTArray; -/* static */ void -nsTableFrame::DestroyPositionedTablePartArray(void* aPropertyValue) -{ - auto positionedObjs = static_cast(aPropertyValue); - delete positionedObjs; -} - /* static */ void nsTableFrame::RegisterPositionedTablePart(nsIFrame* aFrame) { @@ -2549,14 +2542,7 @@ nsTableFrame::GetUsedMargin() const return nsMargin(0, 0, 0, 0); } -// Destructor function for BCPropertyData properties -static void -DestroyBCProperty(void* aPropertyValue) -{ - delete static_cast(aPropertyValue); -} - -NS_DECLARE_FRAME_PROPERTY(TableBCProperty, DestroyBCProperty) +NS_DECLARE_FRAME_PROPERTY(TableBCProperty, DeleteValue) BCPropertyData* nsTableFrame::GetBCProperty(bool aCreateIfNecessary) const diff --git a/layout/tables/nsTableFrame.h b/layout/tables/nsTableFrame.h index 95640a7ef3da..fc254901b30a 100644 --- a/layout/tables/nsTableFrame.h +++ b/layout/tables/nsTableFrame.h @@ -109,8 +109,8 @@ class nsTableFrame : public nsContainerFrame public: NS_DECL_FRAMEARENA_HELPERS - static void DestroyPositionedTablePartArray(void* aPropertyValue); - NS_DECLARE_FRAME_PROPERTY(PositionedTablePartArray, DestroyPositionedTablePartArray) + NS_DECLARE_FRAME_PROPERTY(PositionedTablePartArray, + DeleteValue>) /** nsTableOuterFrame has intimate knowledge of the inner table frame */ friend class nsTableOuterFrame; diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp index 35e29268d5f3..5820c8d70110 100644 --- a/layout/tables/nsTableRowGroupFrame.cpp +++ b/layout/tables/nsTableRowGroupFrame.cpp @@ -1832,13 +1832,8 @@ nsTableRowGroupFrame::GetNextSiblingOnLine(nsIFrame*& aFrame, //end nsLineIterator methods -static void -DestroyFrameCursorData(void* aPropertyValue) -{ - delete static_cast(aPropertyValue); -} - -NS_DECLARE_FRAME_PROPERTY(RowCursorProperty, DestroyFrameCursorData) +NS_DECLARE_FRAME_PROPERTY(RowCursorProperty, + DeleteValue) void nsTableRowGroupFrame::ClearRowCursor() From 60013c0d28c60733654aaab7d74e511f11bf6d27 Mon Sep 17 00:00:00 2001 From: Alexander Surkov Date: Wed, 4 Feb 2015 18:33:33 -0500 Subject: [PATCH 47/74] Bug 786143 - inherit aria-hidden through subtree, r=yzen --- accessible/base/ARIAMap.cpp | 11 ++++++++- accessible/base/ARIAMap.h | 5 ++++ accessible/base/nsAccessiblePivot.cpp | 6 +---- accessible/generic/Accessible.cpp | 22 +++++++++++++++++ accessible/generic/Accessible.h | 12 ++++++++-- accessible/generic/DocAccessible.cpp | 16 +++++++++++++ .../mochitest/events/test_aria_objattr.html | 24 +++++++++++++++++-- 7 files changed, 86 insertions(+), 10 deletions(-) diff --git a/accessible/base/ARIAMap.cpp b/accessible/base/ARIAMap.cpp index aad9126f564d..b4d90ca5ca27 100644 --- a/accessible/base/ARIAMap.cpp +++ b/accessible/base/ARIAMap.cpp @@ -711,7 +711,7 @@ static const AttrCharacteristics gWAIUnivAttrMap[] = { {&nsGkAtoms::aria_flowto, ATTR_BYPASSOBJ | ATTR_GLOBAL }, {&nsGkAtoms::aria_grabbed, ATTR_VALTOKEN | ATTR_GLOBAL }, {&nsGkAtoms::aria_haspopup, ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL }, - {&nsGkAtoms::aria_hidden, ATTR_BYPASSOBJ_IF_FALSE | ATTR_VALTOKEN | ATTR_GLOBAL }, + {&nsGkAtoms::aria_hidden, ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL }, /* handled special way */ {&nsGkAtoms::aria_invalid, ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL }, {&nsGkAtoms::aria_label, ATTR_BYPASSOBJ | ATTR_GLOBAL }, {&nsGkAtoms::aria_labelledby, ATTR_BYPASSOBJ | ATTR_GLOBAL }, @@ -798,6 +798,15 @@ aria::AttrCharacteristicsFor(nsIAtom* aAtom) return 0; } +bool +aria::HasDefinedARIAHidden(nsIContent* aContent) +{ + return aContent && + nsAccUtils::HasDefinedARIAToken(aContent, nsGkAtoms::aria_hidden) && + !aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::aria_hidden, + nsGkAtoms::_false, eCaseMatters); +} + //////////////////////////////////////////////////////////////////////////////// // AttrIterator class diff --git a/accessible/base/ARIAMap.h b/accessible/base/ARIAMap.h index b629b51c22ea..bfb9d11c3fe2 100644 --- a/accessible/base/ARIAMap.h +++ b/accessible/base/ARIAMap.h @@ -227,6 +227,11 @@ uint64_t UniversalStatesFor(mozilla::dom::Element* aElement); */ uint8_t AttrCharacteristicsFor(nsIAtom* aAtom); +/** + * Return true if the element has defined aria-hidden. + */ +bool HasDefinedARIAHidden(nsIContent* aContent); + /** * Represents a simple enumerator for iterating through ARIA attributes * exposed as object attributes on a given accessible. diff --git a/accessible/base/nsAccessiblePivot.cpp b/accessible/base/nsAccessiblePivot.cpp index 371801e56539..3d33f467e821 100644 --- a/accessible/base/nsAccessiblePivot.cpp +++ b/accessible/base/nsAccessiblePivot.cpp @@ -892,11 +892,7 @@ RuleCache::ApplyFilter(Accessible* aAccessible, uint16_t* aResult) return NS_OK; if (nsIAccessibleTraversalRule::PREFILTER_ARIA_HIDDEN & mPreFilter) { - nsIContent* content = aAccessible->GetContent(); - if (content && - nsAccUtils::HasDefinedARIAToken(content, nsGkAtoms::aria_hidden) && - !content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::aria_hidden, - nsGkAtoms::_false, eCaseMatters)) { + if (aAccessible->IsARIAHidden()) { *aResult |= nsIAccessibleTraversalRule::FILTER_IGNORE_SUBTREE; return NS_OK; } diff --git a/accessible/generic/Accessible.cpp b/accessible/generic/Accessible.cpp index b5c96a0eb559..2ad00f7a5a87 100644 --- a/accessible/generic/Accessible.cpp +++ b/accessible/generic/Accessible.cpp @@ -873,6 +873,11 @@ Accessible::Attributes() while(attribIter.Next(name, value)) attributes->SetStringProperty(NS_ConvertUTF16toUTF8(name), value, unused); + if (IsARIAHidden()) { + nsAccUtils::SetAccAttr(attributes, nsGkAtoms::hidden, + NS_LITERAL_STRING("true")); + } + // If there is no aria-live attribute then expose default value of 'live' // object attribute used for ARIA role of this accessible. if (mRoleMapEntry) { @@ -1920,6 +1925,9 @@ Accessible::BindToParent(Accessible* aParent, uint32_t aIndexInParent) mContextFlags |= eHasNameDependentParent; else mContextFlags &= ~eHasNameDependentParent; + + if (mParent->IsARIAHidden() || aria::HasDefinedARIAHidden(mContent)) + SetARIAHidden(true); } // Accessible protected @@ -2377,6 +2385,20 @@ Accessible::ContainerWidget() const return nullptr; } +void +Accessible::SetARIAHidden(bool aIsDefined) +{ + if (aIsDefined) + mContextFlags |= eARIAHidden; + else + mContextFlags &= ~eARIAHidden; + + uint32_t length = mChildren.Length(); + for (uint32_t i = 0; i < length; i++) { + mChildren[i]->SetARIAHidden(aIsDefined); + } +} + //////////////////////////////////////////////////////////////////////////////// // Accessible protected methods diff --git a/accessible/generic/Accessible.h b/accessible/generic/Accessible.h index bc33a1ac93ec..540859cd9672 100644 --- a/accessible/generic/Accessible.h +++ b/accessible/generic/Accessible.h @@ -889,6 +889,13 @@ public: bool HasNameDependentParent() const { return mContextFlags & eHasNameDependentParent; } + /** + * Return true if aria-hidden="true" is applied to the accessible or inherited + * from the parent. + */ + bool IsARIAHidden() const { return mContextFlags & eARIAHidden; } + void SetARIAHidden(bool aIsDefined); + protected: virtual ~Accessible(); @@ -975,8 +982,9 @@ protected: */ enum ContextFlags { eHasNameDependentParent = 1 << 0, // Parent's name depends on this accessible. + eARIAHidden = 1 << 1, - eLastContextFlag = eHasNameDependentParent + eLastContextFlag = eARIAHidden }; protected: @@ -1082,7 +1090,7 @@ protected: static const uint8_t kChildrenFlagsBits = 2; static const uint8_t kStateFlagsBits = 9; - static const uint8_t kContextFlagsBits = 1; + static const uint8_t kContextFlagsBits = 2; static const uint8_t kTypeBits = 6; static const uint8_t kGenericTypesBits = 13; diff --git a/accessible/generic/DocAccessible.cpp b/accessible/generic/DocAccessible.cpp index 7c72a7390ec1..862e5b452c24 100644 --- a/accessible/generic/DocAccessible.cpp +++ b/accessible/generic/DocAccessible.cpp @@ -955,6 +955,22 @@ DocAccessible::ARIAAttributeChanged(Accessible* aAccessible, nsIAtom* aAttribute nsIContent* elm = aAccessible->GetContent(); + // Update aria-hidden flag for the whole subtree iff aria-hidden is changed + // on the root, i.e. ignore any affiliated aria-hidden changes in the subtree + // of top aria-hidden. + if (aAttribute == nsGkAtoms::aria_hidden) { + bool isDefined = aria::HasDefinedARIAHidden(elm); + if (isDefined != aAccessible->IsARIAHidden() && + !aAccessible->Parent()->IsARIAHidden()) { + aAccessible->SetARIAHidden(isDefined); + + nsRefPtr event = + new AccObjectAttrChangedEvent(aAccessible, aAttribute); + FireDelayedEvent(event); + } + return; + } + if (aAttribute == nsGkAtoms::aria_checked || (aAccessible->IsButton() && aAttribute == nsGkAtoms::aria_pressed)) { diff --git a/accessible/tests/mochitest/events/test_aria_objattr.html b/accessible/tests/mochitest/events/test_aria_objattr.html index 1410a53c0e6b..5f16ba7948e5 100644 --- a/accessible/tests/mochitest/events/test_aria_objattr.html +++ b/accessible/tests/mochitest/events/test_aria_objattr.html @@ -11,6 +11,8 @@ + @@ -40,6 +42,23 @@ }; } + function updateARIAHidden(aID, aIsDefined, aChildId) + { + this.__proto__ = new updateAttribute(aID, "aria-hidden", + aIsDefined ? "true" : "false"); + + this.finalCheck = function updateARIAHidden() + { + if (aIsDefined) { + testAttrs(aID, {"hidden" : "true"}, true); + testAttrs(aChildId, {"hidden" : "true"}, true); + } else { + testAbsentAttrs(aID, { "hidden": "true"}); + testAbsentAttrs(aChildId, { "hidden": "true"}); + } + } + } + // Debug stuff. // gA11yEventDumpID = "eventdump"; //gA11yEventDumpToConsole = true; @@ -48,7 +67,8 @@ { gQueue = new eventQueue(); - gQueue.push(new updateAttribute("hideable", "aria-hidden", "true")); + gQueue.push(new updateARIAHidden("hideable", true, "hideable_child")); + gQueue.push(new updateARIAHidden("hideable", false, "hideable_child")); gQueue.push(new updateAttribute("sortable", "aria-sort", "ascending")); @@ -89,7 +109,7 @@
-
Hi
there
+
Hi
there
aria-sort
From 8854feaf734126a70b4e2486efa6a5534f3ee45e Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Wed, 4 Feb 2015 16:07:04 -0800 Subject: [PATCH 48/74] Bug 1128061 - Check unhandlable OOM when finishing off-thread Ion compiles. (r=terrence) --- js/src/vm/HelperThreads.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/js/src/vm/HelperThreads.cpp b/js/src/vm/HelperThreads.cpp index 73bfcb2b9f7a..a022b33e6579 100644 --- a/js/src/vm/HelperThreads.cpp +++ b/js/src/vm/HelperThreads.cpp @@ -116,7 +116,8 @@ js::StartOffThreadIonCompile(JSContext *cx, jit::IonBuilder *builder) static void FinishOffThreadIonCompile(jit::IonBuilder *builder) { - HelperThreadState().ionFinishedList().append(builder); + if (!HelperThreadState().ionFinishedList().append(builder)) + CrashAtUnhandlableOOM("FinishOffThreadIonCompile"); } static inline bool From 680ae080b6a68960a3d7129097b84201fc3a2a51 Mon Sep 17 00:00:00 2001 From: Jeff Gilbert Date: Wed, 4 Feb 2015 16:34:55 -0800 Subject: [PATCH 49/74] Bug 1124394 - Support WebGL 2 with Core Profiles on Mac. - r=kamidphish --- dom/canvas/WebGLContext.cpp | 28 +- dom/canvas/WebGLContext.h | 3 +- dom/canvas/WebGLContextGL.cpp | 1 - dom/canvas/WebGLContextUtils.cpp | 9 +- dom/canvas/WebGLContextValidate.cpp | 6 +- .../fmp4/android/AndroidDecoderModule.cpp | 2 +- dom/plugins/base/nsNPAPIPluginInstance.cpp | 5 +- gfx/gl/GLContext.cpp | 246 ++++++++++-------- gfx/gl/GLContext.h | 107 ++++---- gfx/gl/GLContextCGL.h | 6 +- gfx/gl/GLContextFeatures.cpp | 10 + gfx/gl/GLContextProviderCGL.mm | 163 +++++++----- gfx/gl/GLContextProviderEGL.cpp | 7 +- gfx/gl/GLContextProviderGLX.cpp | 7 +- gfx/gl/GLContextProviderImpl.h | 5 +- gfx/gl/GLContextProviderNull.cpp | 5 +- gfx/gl/GLContextProviderWGL.cpp | 7 +- gfx/gl/GLContextSymbols.h | 4 + gfx/gl/GLContextTypes.cpp | 5 - gfx/gl/GLContextTypes.h | 13 - gfx/gl/GLLibraryEGL.cpp | 26 +- gfx/gl/GLLibraryEGL.h | 1 + gfx/layers/GLImages.cpp | 2 +- gfx/layers/opengl/CompositorOGL.cpp | 5 +- gfx/tests/gtest/TestCompositor.cpp | 2 +- gfx/thebes/gfxPlatform.cpp | 5 +- widget/android/GfxInfo.cpp | 4 +- 27 files changed, 376 insertions(+), 308 deletions(-) diff --git a/dom/canvas/WebGLContext.cpp b/dom/canvas/WebGLContext.cpp index 749621074af9..38420ff232e2 100644 --- a/dom/canvas/WebGLContext.cpp +++ b/dom/canvas/WebGLContext.cpp @@ -505,7 +505,7 @@ IsFeatureInBlacklist(const nsCOMPtr& gfxInfo, int32_t feature) static already_AddRefed CreateHeadlessNativeGL(bool forceEnabled, const nsCOMPtr& gfxInfo, - WebGLContext* webgl) + bool requireCompatProfile, WebGLContext* webgl) { if (!forceEnabled && IsFeatureInBlacklist(gfxInfo, nsIGfxInfo::FEATURE_WEBGL_OPENGL)) @@ -515,7 +515,7 @@ CreateHeadlessNativeGL(bool forceEnabled, const nsCOMPtr& gfxInfo, return nullptr; } - nsRefPtr gl = gl::GLContextProvider::CreateHeadless(); + nsRefPtr gl = gl::GLContextProvider::CreateHeadless(requireCompatProfile); if (!gl) { webgl->GenerateWarning("Error during native OpenGL init."); return nullptr; @@ -530,7 +530,7 @@ CreateHeadlessNativeGL(bool forceEnabled, const nsCOMPtr& gfxInfo, // Eventually, we want to be able to pick ANGLE-EGL or native EGL. static already_AddRefed CreateHeadlessANGLE(bool forceEnabled, const nsCOMPtr& gfxInfo, - WebGLContext* webgl) + bool requireCompatProfile, WebGLContext* webgl) { nsRefPtr gl; @@ -543,7 +543,7 @@ CreateHeadlessANGLE(bool forceEnabled, const nsCOMPtr& gfxInfo, return nullptr; } - gl = gl::GLContextProviderEGL::CreateHeadless(); + gl = gl::GLContextProviderEGL::CreateHeadless(requireCompatProfile); if (!gl) { webgl->GenerateWarning("Error during ANGLE OpenGL init."); return nullptr; @@ -555,13 +555,13 @@ CreateHeadlessANGLE(bool forceEnabled, const nsCOMPtr& gfxInfo, } static already_AddRefed -CreateHeadlessEGL(bool forceEnabled, const nsCOMPtr& gfxInfo, +CreateHeadlessEGL(bool forceEnabled, bool requireCompatProfile, WebGLContext* webgl) { nsRefPtr gl; #ifdef ANDROID - gl = gl::GLContextProviderEGL::CreateHeadless(); + gl = gl::GLContextProviderEGL::CreateHeadless(requireCompatProfile); if (!gl) { webgl->GenerateWarning("Error during EGL OpenGL init."); return nullptr; @@ -583,16 +583,22 @@ CreateHeadlessGL(bool forceEnabled, const nsCOMPtr& gfxInfo, if (PR_GetEnv("MOZ_WEBGL_FORCE_OPENGL")) disableANGLE = true; + bool requireCompatProfile = webgl->IsWebGL2() ? false : true; + nsRefPtr gl; if (preferEGL) - gl = CreateHeadlessEGL(forceEnabled, gfxInfo, webgl); + gl = CreateHeadlessEGL(forceEnabled, requireCompatProfile, webgl); - if (!gl && !disableANGLE) - gl = CreateHeadlessANGLE(forceEnabled, gfxInfo, webgl); + if (!gl && !disableANGLE) { + gl = CreateHeadlessANGLE(forceEnabled, gfxInfo, requireCompatProfile, + webgl); + } - if (!gl) - gl = CreateHeadlessNativeGL(forceEnabled, gfxInfo, webgl); + if (!gl) { + gl = CreateHeadlessNativeGL(forceEnabled, gfxInfo, + requireCompatProfile, webgl); + } return gl.forget(); } diff --git a/dom/canvas/WebGLContext.h b/dom/canvas/WebGLContext.h index dabdd737782f..fdaada5f80b0 100644 --- a/dom/canvas/WebGLContext.h +++ b/dom/canvas/WebGLContext.h @@ -1209,9 +1209,10 @@ protected: // ------------------------------------------------------------------------- // WebGL 2 specifics (implemented in WebGL2Context.cpp) - +public: virtual bool IsWebGL2() const = 0; +protected: bool InitWebGL2(); // ------------------------------------------------------------------------- diff --git a/dom/canvas/WebGLContextGL.cpp b/dom/canvas/WebGLContextGL.cpp index 999b71b67e42..1e4d4c1b370a 100644 --- a/dom/canvas/WebGLContextGL.cpp +++ b/dom/canvas/WebGLContextGL.cpp @@ -2106,7 +2106,6 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width, // if we're reading alpha, we may need to do fixup. Note that we don't allow // GL_ALPHA to readpixels currently, but we had the code written for it already. - const bool formatHasAlpha = format == LOCAL_GL_ALPHA || format == LOCAL_GL_RGBA; if (!formatHasAlpha) diff --git a/dom/canvas/WebGLContextUtils.cpp b/dom/canvas/WebGLContextUtils.cpp index b0e02a185770..caba53cac181 100644 --- a/dom/canvas/WebGLContextUtils.cpp +++ b/dom/canvas/WebGLContextUtils.cpp @@ -1117,11 +1117,12 @@ WebGLContext::AssertCachedState() AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_CLEAR_VALUE, mStencilClearValue); GLint stencilBits = 0; - gl->fGetIntegerv(LOCAL_GL_STENCIL_BITS, &stencilBits); - const GLuint stencilRefMask = (1 << stencilBits) - 1; + if (GetStencilBits(&stencilBits)) { + const GLuint stencilRefMask = (1 << stencilBits) - 1; - AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_REF, stencilRefMask, mStencilRefFront); - AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_REF, stencilRefMask, mStencilRefBack); + AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_REF, stencilRefMask, mStencilRefFront); + AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_REF, stencilRefMask, mStencilRefBack); + } // GLES 3.0.4, $4.1.4, p177: // [...] the front and back stencil mask are both set to the value `2^s - 1`, where diff --git a/dom/canvas/WebGLContextValidate.cpp b/dom/canvas/WebGLContextValidate.cpp index 1dbc000a1416..e942610793b9 100644 --- a/dom/canvas/WebGLContextValidate.cpp +++ b/dom/canvas/WebGLContextValidate.cpp @@ -1779,8 +1779,8 @@ WebGLContext::InitAndValidateGL() MakeContextCurrent(); - // on desktop OpenGL, we always keep vertex attrib 0 array enabled - if (!gl->IsGLES()) + // For OpenGL compat. profiles, we always keep vertex attrib 0 array enabled. + if (gl->IsCompatibilityProfile()) gl->fEnableVertexAttribArray(0); if (MinCapabilityMode()) @@ -1889,7 +1889,7 @@ WebGLContext::InitAndValidateGL() // Always 1 for GLES2 mMaxFramebufferColorAttachments = 1; - if (!gl->IsGLES()) { + if (gl->IsCompatibilityProfile()) { // gl_PointSize is always available in ES2 GLSL, but has to be // specifically enabled on desktop GLSL. gl->fEnable(LOCAL_GL_VERTEX_PROGRAM_POINT_SIZE); diff --git a/dom/media/fmp4/android/AndroidDecoderModule.cpp b/dom/media/fmp4/android/AndroidDecoderModule.cpp index 84fbd4ef3f54..bd00d07faa7f 100644 --- a/dom/media/fmp4/android/AndroidDecoderModule.cpp +++ b/dom/media/fmp4/android/AndroidDecoderModule.cpp @@ -179,7 +179,7 @@ protected: return true; } - mGLContext = GLContextProvider::CreateHeadless(); + mGLContext = GLContextProvider::CreateHeadless(false); return mGLContext; } diff --git a/dom/plugins/base/nsNPAPIPluginInstance.cpp b/dom/plugins/base/nsNPAPIPluginInstance.cpp index 811b75c31bf3..9f94d76639d1 100644 --- a/dom/plugins/base/nsNPAPIPluginInstance.cpp +++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp @@ -91,9 +91,8 @@ static nsRefPtr sPluginContext = nullptr; static bool EnsureGLContext() { if (!sPluginContext) { - gfxIntSize dummySize(16, 16); - sPluginContext = GLContextProvider::CreateOffscreen(dummySize, - SurfaceCaps::Any()); + bool requireCompatProfile = true; + sPluginContext = GLContextProvider::CreateHeadless(requireCompatProfile); } return sPluginContext != nullptr; diff --git a/gfx/gl/GLContext.cpp b/gfx/gl/GLContext.cpp index b300ddff6085..f84a47c54b02 100644 --- a/gfx/gl/GLContext.cpp +++ b/gfx/gl/GLContext.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "GLContext.h" #include "GLBlitHelper.h" @@ -156,8 +157,7 @@ static const char *sExtensionNames[] = { "GL_OES_texture_half_float", "GL_OES_texture_half_float_linear", "GL_OES_texture_npot", - "GL_OES_vertex_array_object", - nullptr + "GL_OES_vertex_array_object" }; static bool @@ -501,6 +501,8 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl) mInitialized = LoadSymbols(&symbols[0], trygl, prefix); MakeCurrent(); if (mInitialized) { + MOZ_ASSERT(mProfile != ContextProfile::Unknown); + uint32_t version = 0; ParseGLVersion(this, &version); @@ -656,6 +658,15 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl) } } + if (IsFeatureProvidedByCoreSymbols(GLFeature::get_string_indexed)) { + SymLoadStruct moreSymbols[] = { + { (PRFuncPtr*) &mSymbols.fGetStringi, { "GetStringi", nullptr } }, + END_SYMBOLS + }; + + MOZ_ALWAYS_TRUE(LoadSymbols(moreSymbols, trygl, prefix)); + } + InitExtensions(); InitFeatures(); @@ -670,12 +681,6 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl) MarkUnsupported(GLFeature::standard_derivatives); } - if (Vendor() == GLVendor::Imagination && - Renderer() == GLRenderer::SGX540) { - // Bug 980048 - MarkExtensionUnsupported(OES_EGL_sync); - } - if (Renderer() == GLRenderer::MicrosoftBasicRenderDriver) { // Bug 978966: on Microsoft's "Basic Render Driver" (software renderer) // multisampling hardcodes blending with the default blendfunc, which breaks WebGL. @@ -1468,10 +1473,13 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl) // We're ready for final setup. fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0); - if (mCaps.any) - DetermineCaps(); + // TODO: Remove SurfaceCaps::any. + if (mCaps.any) { + mCaps.any = false; + mCaps.color = true; + mCaps.alpha = false; + } - UpdatePixelFormat(); UpdateGLFormats(mCaps); mTexGarbageBin = new TextureGarbageBin(this); @@ -1593,61 +1601,105 @@ GLContext::DebugCallback(GLenum source, void GLContext::InitExtensions() { - MakeCurrent(); - const char* extensions = (const char*)fGetString(LOCAL_GL_EXTENSIONS); - if (!extensions) - return; + MOZ_ASSERT(IsCurrent()); - InitializeExtensionsBitSet(mAvailableExtensions, extensions, - sExtensionNames); + std::vector driverExtensionList; - if (WorkAroundDriverBugs() && - Vendor() == GLVendor::Qualcomm) { + if (IsFeatureProvidedByCoreSymbols(GLFeature::get_string_indexed)) { + GLuint count = 0; + GetUIntegerv(LOCAL_GL_NUM_EXTENSIONS, &count); + for (GLuint i = 0; i < count; i++) { + // This is UTF-8. + const char* rawExt = (const char*)fGetStringi(LOCAL_GL_EXTENSIONS, i); - // Some Adreno drivers do not report GL_OES_EGL_sync, but they really do support it. - MarkExtensionSupported(OES_EGL_sync); + // We CANNOT use nsDependentCString here, because the spec doesn't guarantee + // that the pointers returned are different, only that their contents are. + // On Flame, each of these index string queries returns the same address. + driverExtensionList.push_back(nsCString(rawExt)); + } + } else { + MOZ_ALWAYS_TRUE(!fGetError()); + const char* rawExts = (const char*)fGetString(LOCAL_GL_EXTENSIONS); + MOZ_ALWAYS_TRUE(!fGetError()); + + if (rawExts) { + nsDependentCString exts(rawExts); + SplitByChar(exts, ' ', &driverExtensionList); + } } - if (WorkAroundDriverBugs() && - Renderer() == GLRenderer::AndroidEmulator) { - // the Android emulator, which we use to run B2G reftests on, - // doesn't expose the OES_rgb8_rgba8 extension, but it seems to - // support it (tautologically, as it only runs on desktop GL). - MarkExtensionSupported(OES_rgb8_rgba8); + const bool shouldDumpExts = ShouldDumpExts(); + if (shouldDumpExts) { + printf_stderr("%i GL driver extensions: (*: recognized)\n", + (uint32_t)driverExtensionList.size()); } - if (WorkAroundDriverBugs() && - Vendor() == GLVendor::VMware && - Renderer() == GLRenderer::GalliumLlvmpipe) - { - // The llvmpipe driver that is used on linux try servers appears to have - // buggy support for s3tc/dxt1 compressed textures. - // See Bug 975824. - MarkExtensionUnsupported(EXT_texture_compression_s3tc); - MarkExtensionUnsupported(EXT_texture_compression_dxt1); - MarkExtensionUnsupported(ANGLE_texture_compression_dxt3); - MarkExtensionUnsupported(ANGLE_texture_compression_dxt5); - } + MarkBitfieldByStrings(driverExtensionList, shouldDumpExts, sExtensionNames, + &mAvailableExtensions); + + if (WorkAroundDriverBugs()) { + if (Vendor() == GLVendor::Qualcomm) { + // Some Adreno drivers do not report GL_OES_EGL_sync, but they really do support it. + MarkExtensionSupported(OES_EGL_sync); + } + + if (Vendor() == GLVendor::Imagination && + Renderer() == GLRenderer::SGX540) + { + // Bug 980048 + MarkExtensionUnsupported(OES_EGL_sync); + } + + if (Renderer() == GLRenderer::AndroidEmulator) { + // the Android emulator, which we use to run B2G reftests on, + // doesn't expose the OES_rgb8_rgba8 extension, but it seems to + // support it (tautologically, as it only runs on desktop GL). + MarkExtensionSupported(OES_rgb8_rgba8); + } + + if (Vendor() == GLVendor::VMware && + Renderer() == GLRenderer::GalliumLlvmpipe) + { + // The llvmpipe driver that is used on linux try servers appears to have + // buggy support for s3tc/dxt1 compressed textures. + // See Bug 975824. + MarkExtensionUnsupported(EXT_texture_compression_s3tc); + MarkExtensionUnsupported(EXT_texture_compression_dxt1); + MarkExtensionUnsupported(ANGLE_texture_compression_dxt3); + MarkExtensionUnsupported(ANGLE_texture_compression_dxt5); + } #ifdef XP_MACOSX - // Bug 1009642: On OSX Mavericks (10.9), the driver for Intel HD - // 3000 appears to be buggy WRT updating sub-images of S3TC - // textures with glCompressedTexSubImage2D. Works on Intel HD 4000 - // and Intel HD 5000/Iris that I tested. - if (WorkAroundDriverBugs() && - nsCocoaFeatures::OSXVersionMajor() == 10 && - nsCocoaFeatures::OSXVersionMinor() == 9 && - Renderer() == GLRenderer::IntelHD3000) - { - MarkExtensionUnsupported(EXT_texture_compression_s3tc); - } + // Bug 1009642: On OSX Mavericks (10.9), the driver for Intel HD + // 3000 appears to be buggy WRT updating sub-images of S3TC + // textures with glCompressedTexSubImage2D. Works on Intel HD 4000 + // and Intel HD 5000/Iris that I tested. + if (nsCocoaFeatures::OSXVersionMajor() == 10 && + nsCocoaFeatures::OSXVersionMinor() == 9 && + Renderer() == GLRenderer::IntelHD3000) + { + MarkExtensionUnsupported(EXT_texture_compression_s3tc); + } #endif + } + + if (shouldDumpExts) { + printf_stderr("\nActivated extensions:\n"); + + for (size_t i = 0; i < mAvailableExtensions.size(); i++) { + if (!mAvailableExtensions[i]) + continue; + + const char* ext = sExtensionNames[i]; + printf_stderr("[%i] %s\n", (uint32_t)i, ext); + } + } } void GLContext::PlatformStartup() { - RegisterStrongMemoryReporter(new GfxTexturesReporter()); + RegisterStrongMemoryReporter(new GfxTexturesReporter()); } // Common code for checking for both GL extensions and GLX extensions. @@ -1688,66 +1740,6 @@ GLContext::ListHasExtension(const GLubyte *extensions, const char *extension) return false; } -void -GLContext::DetermineCaps() -{ - PixelBufferFormat format = QueryPixelFormat(); - - SurfaceCaps caps; - caps.color = !!format.red && !!format.green && !!format.blue; - caps.bpp16 = caps.color && format.ColorBits() == 16; - caps.alpha = !!format.alpha; - caps.depth = !!format.depth; - caps.stencil = !!format.stencil; - caps.antialias = format.samples > 1; - caps.preserve = true; - - mCaps = caps; -} - -PixelBufferFormat -GLContext::QueryPixelFormat() -{ - PixelBufferFormat format; - - ScopedBindFramebuffer autoFB(this, 0); - - fGetIntegerv(LOCAL_GL_RED_BITS , &format.red ); - fGetIntegerv(LOCAL_GL_GREEN_BITS, &format.green); - fGetIntegerv(LOCAL_GL_BLUE_BITS , &format.blue ); - fGetIntegerv(LOCAL_GL_ALPHA_BITS, &format.alpha); - - fGetIntegerv(LOCAL_GL_DEPTH_BITS, &format.depth); - fGetIntegerv(LOCAL_GL_STENCIL_BITS, &format.stencil); - - fGetIntegerv(LOCAL_GL_SAMPLES, &format.samples); - - return format; -} - -void -GLContext::UpdatePixelFormat() -{ - PixelBufferFormat format = QueryPixelFormat(); -#ifdef MOZ_GL_DEBUG - const SurfaceCaps& caps = Caps(); - MOZ_ASSERT(!caps.any, "Did you forget to DetermineCaps()?"); - - MOZ_ASSERT(caps.color == !!format.red); - MOZ_ASSERT(caps.color == !!format.green); - MOZ_ASSERT(caps.color == !!format.blue); - - // These we either must have if they're requested, or - // we can have if they're not. - MOZ_ASSERT(caps.alpha == !!format.alpha || !caps.alpha); - MOZ_ASSERT(caps.depth == !!format.depth || !caps.depth); - MOZ_ASSERT(caps.stencil == !!format.stencil || !caps.stencil); - - MOZ_ASSERT(caps.antialias == (format.samples > 1)); -#endif - mPixelFormat = new PixelBufferFormat(format); -} - GLFormats GLContext::ChooseGLFormats(const SurfaceCaps& caps) const { @@ -2417,6 +2409,13 @@ GLContext::FlushIfHeavyGLCallsSinceLastFlush() fFlush(); } +/*static*/ bool +GLContext::ShouldDumpExts() +{ + static bool ret = PR_GetEnv("MOZ_GL_DUMP_EXTS"); + return ret; +} + bool DoesStringMatch(const char* aString, const char *aWantedString) { @@ -2444,8 +2443,29 @@ DoesStringMatch(const char* aString, const char *aWantedString) /*static*/ bool GLContext::ShouldSpew() { - static bool spew = PR_GetEnv("MOZ_GL_SPEW"); - return spew; + static bool ret = PR_GetEnv("MOZ_GL_SPEW"); + return ret; +} + +void +SplitByChar(const nsACString& str, const char delim, std::vector* const out) +{ + uint32_t start = 0; + while (true) { + int32_t end = str.FindChar(' ', start); + if (end == -1) + break; + + uint32_t len = (uint32_t)end - start; + nsDependentCSubstring substr(str, start, len); + out->push_back(nsCString(substr)); + + start = end + 1; + continue; + } + + nsDependentCSubstring substr(str, start); + out->push_back(nsCString(substr)); } } /* namespace gl */ diff --git a/gfx/gl/GLContext.h b/gfx/gl/GLContext.h index 9cc3a0906344..cc6d8fcf2a42 100644 --- a/gfx/gl/GLContext.h +++ b/gfx/gl/GLContext.h @@ -104,6 +104,7 @@ enum class GLFeature { get_integer_indexed, get_integer64_indexed, get_query_object_iv, + get_string_indexed, gpu_shader4, instanced_arrays, instanced_non_arrays, @@ -308,7 +309,6 @@ public: virtual bool IsCurrent() = 0; protected: - bool mInitialized; bool mIsOffscreen; bool mIsGlobalSharedContext; @@ -325,9 +325,12 @@ protected: GLVendor mVendor; GLRenderer mRenderer; - inline void SetProfileVersion(ContextProfile profile, unsigned int version) { - MOZ_ASSERT(!mInitialized, "SetProfileVersion can only be called before initialization!"); - MOZ_ASSERT(profile != ContextProfile::Unknown && profile != ContextProfile::OpenGL, "Invalid `profile` for SetProfileVersion"); + void SetProfileVersion(ContextProfile profile, uint32_t version) { + MOZ_ASSERT(!mInitialized, "SetProfileVersion can only be called before" + " initialization!"); + MOZ_ASSERT(profile != ContextProfile::Unknown && + profile != ContextProfile::OpenGL, + "Invalid `profile` for SetProfileVersion"); MOZ_ASSERT(version >= 100, "Invalid `version` for SetProfileVersion"); mVersion = version; @@ -457,6 +460,7 @@ public: return mAvailableExtensions[aKnownExtension]; } +protected: void MarkExtensionUnsupported(GLExtensions aKnownExtension) { mAvailableExtensions[aKnownExtension] = 0; } @@ -465,42 +469,6 @@ public: mAvailableExtensions[aKnownExtension] = 1; } -public: - template - static void InitializeExtensionsBitSet(std::bitset& extensionsBitset, - const char* extStr, - const char** extList) - { - char* exts = ::strdup(extStr); - - if (ShouldSpew()) - printf_stderr("Extensions: %s\n", exts); - - char* cur = exts; - bool done = false; - while (!done) { - char* space = strchr(cur, ' '); - if (space) { - *space = '\0'; - } else { - done = true; - } - - for (int i = 0; extList[i]; ++i) { - if (PL_strcasecmp(cur, extList[i]) == 0) { - if (ShouldSpew()) - printf_stderr("Found extension %s\n", cur); - extensionsBitset[i] = true; - } - } - - cur = space + 1; - } - - free(exts); - } - -protected: std::bitset mAvailableExtensions; // ----------------------------------------------------------------------------- @@ -3180,6 +3148,17 @@ public: AFTER_GL_CALL; } +// ----------------------------------------------------------------------------- +// get_string_indexed + + const GLubyte* fGetStringi(GLenum name, GLuint index) { + BEFORE_GL_CALL; + ASSERT_SYMBOL_PRESENT(fGetStringi); + const GLubyte* ret = mSymbols.fGetStringi(name, index); + AFTER_GL_CALL; + return ret; + } + // ----------------------------------------------------------------------------- // Constructor protected: @@ -3448,11 +3427,9 @@ public: fViewport(0, 0, size.width, size.height); mCaps = mScreen->mCaps; - if (mCaps.any) - DetermineCaps(); + MOZ_ASSERT(!mCaps.any); UpdateGLFormats(mCaps); - UpdatePixelFormat(); return true; } @@ -3475,10 +3452,8 @@ public: protected: SurfaceCaps mCaps; nsAutoPtr mGLFormats; - nsAutoPtr mPixelFormat; public: - void DetermineCaps(); const SurfaceCaps& Caps() const { return mCaps; } @@ -3494,14 +3469,6 @@ public: return *mGLFormats; } - PixelBufferFormat QueryPixelFormat(); - void UpdatePixelFormat(); - - const PixelBufferFormat& GetPixelFormat() const { - MOZ_ASSERT(mPixelFormat); - return *mPixelFormat; - } - bool IsFramebufferComplete(GLuint fb, GLenum* status = nullptr); // Does not check completeness. @@ -3541,7 +3508,7 @@ public: } bool IsOffscreen() const { - return !!mScreen; + return mIsOffscreen; } GLScreenBuffer* Screen() const { @@ -3696,10 +3663,42 @@ protected: public: void FlushIfHeavyGLCallsSinceLastFlush(); static bool ShouldSpew(); + static bool ShouldDumpExts(); }; bool DoesStringMatch(const char* aString, const char *aWantedString); +void SplitByChar(const nsACString& str, const char delim, + std::vector* const out); + +template +bool +MarkBitfieldByString(const nsACString& str, const char* (&markStrList)[N], + std::bitset* const out_markList) +{ + for (size_t i = 0; i < N; i++) { + if (str.Equals(markStrList[i])) { + (*out_markList)[i] = 1; + return true; + } + } + return false; +} + +template +void +MarkBitfieldByStrings(const std::vector& strList, + bool dumpStrings, const char* (&markStrList)[N], + std::bitset* const out_markList) +{ + for (auto itr = strList.begin(); itr != strList.end(); ++itr) { + const nsACString& str = *itr; + const bool wasMarked = MarkBitfieldByString(str, markStrList, + out_markList); + if (dumpStrings) + printf_stderr(" %s%s\n", str.BeginReading(), wasMarked ? "(*)" : ""); + } +} } /* namespace gl */ } /* namespace mozilla */ diff --git a/gfx/gl/GLContextCGL.h b/gfx/gl/GLContextCGL.h index 9b3c52ddd8e5..5da7085450cb 100644 --- a/gfx/gl/GLContextCGL.h +++ b/gfx/gl/GLContextCGL.h @@ -28,10 +28,8 @@ class GLContextCGL : public GLContext public: MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GLContextCGL, MOZ_OVERRIDE) - GLContextCGL(const SurfaceCaps& caps, - GLContext *shareContext, - NSOpenGLContext *context, - bool isOffscreen = false); + GLContextCGL(const SurfaceCaps& caps, NSOpenGLContext* context, + bool isOffscreen, ContextProfile profile); ~GLContextCGL(); diff --git a/gfx/gl/GLContextFeatures.cpp b/gfx/gl/GLContextFeatures.cpp index 0e47ecbae087..ed2fa69ec9e2 100644 --- a/gfx/gl/GLContextFeatures.cpp +++ b/gfx/gl/GLContextFeatures.cpp @@ -274,6 +274,16 @@ static const FeatureInfo sFeatureInfoArr[] = { * ARB_occlusion_query (added by OpenGL 2.0). */ }, + { + "get_string_indexed", + GLVersion::GL3, + GLESVersion::ES3, + GLContext::Extension_None, + { + GLContext::Extensions_End + } + // glGetStringi + }, { "gpu_shader4", GLVersion::GL3, diff --git a/gfx/gl/GLContextProviderCGL.mm b/gfx/gl/GLContextProviderCGL.mm index 3492e4ab4eac..a5c3a9baf3e6 100644 --- a/gfx/gl/GLContextProviderCGL.mm +++ b/gfx/gl/GLContextProviderCGL.mm @@ -21,16 +21,14 @@ namespace gl { using namespace mozilla::gfx; -static bool gUseDoubleBufferedWindows = true; - class CGLLibrary { public: CGLLibrary() - : mInitialized(false), - mOGLLibrary(nullptr), - mPixelFormat(nullptr) - { } + : mInitialized(false) + , mUseDoubleBufferedWindows(true) + , mOGLLibrary(nullptr) + {} bool EnsureInitialized() { @@ -46,48 +44,33 @@ public: } const char* db = PR_GetEnv("MOZ_CGL_DB"); - gUseDoubleBufferedWindows = (!db || *db != '0'); + if (db) { + mUseDoubleBufferedWindows = *db != '0'; + } mInitialized = true; return true; } - NSOpenGLPixelFormat *PixelFormat() - { - if (mPixelFormat == nullptr) { - NSOpenGLPixelFormatAttribute attribs[] = { - NSOpenGLPFAAccelerated, - NSOpenGLPFAAllowOfflineRenderers, - NSOpenGLPFADoubleBuffer, - 0 - }; - - if (!gUseDoubleBufferedWindows) { - attribs[2] = 0; - } - - mPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs]; - } - - return mPixelFormat; + bool UseDoubleBufferedWindows() const { + MOZ_ASSERT(mInitialized); + return mUseDoubleBufferedWindows; } + private: bool mInitialized; + bool mUseDoubleBufferedWindows; PRLibrary *mOGLLibrary; - NSOpenGLPixelFormat *mPixelFormat; }; CGLLibrary sCGLLibrary; -GLContextCGL::GLContextCGL( - const SurfaceCaps& caps, - GLContext *shareContext, - NSOpenGLContext *context, - bool isOffscreen) - : GLContext(caps, shareContext, isOffscreen), - mContext(context) +GLContextCGL::GLContextCGL(const SurfaceCaps& caps, NSOpenGLContext* context, + bool isOffscreen, ContextProfile profile) + : GLContext(caps, nullptr, isOffscreen) + , mContext(context) { - SetProfileVersion(ContextProfile::OpenGLCompatibility, 210); + SetProfileVersion(profile, 210); } GLContextCGL::~GLContextCGL() @@ -162,7 +145,7 @@ GLContextCGL::SetupLookupFunction() bool GLContextCGL::IsDoubleBuffered() const { - return gUseDoubleBufferedWindows; + return sCGLLibrary.UseDoubleBufferedWindows(); } bool @@ -182,26 +165,66 @@ GLContextCGL::SwapBuffers() } -static GLContextCGL * -GetGlobalContextCGL() -{ - return static_cast(GLContextProviderCGL::GetGlobalContext()); -} - already_AddRefed GLContextProviderCGL::CreateWrappingExisting(void*, void*) { return nullptr; } +static const NSOpenGLPixelFormatAttribute kAttribs_singleBuffered[] = { + NSOpenGLPFAAccelerated, + NSOpenGLPFAAllowOfflineRenderers, + 0 +}; + +static const NSOpenGLPixelFormatAttribute kAttribs_doubleBuffered[] = { + NSOpenGLPFAAccelerated, + NSOpenGLPFAAllowOfflineRenderers, + NSOpenGLPFADoubleBuffer, + 0 +}; + +static const NSOpenGLPixelFormatAttribute kAttribs_offscreen[] = { + NSOpenGLPFAPixelBuffer, + 0 +}; + +static const NSOpenGLPixelFormatAttribute kAttribs_offscreen_coreProfile[] = { + NSOpenGLPFAAccelerated, + NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core, + 0 +}; + +static NSOpenGLContext* +CreateWithFormat(const NSOpenGLPixelFormatAttribute* attribs) +{ + NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc] + initWithAttributes:attribs]; + if (!format) + return nullptr; + + NSOpenGLContext* context = [[NSOpenGLContext alloc] initWithFormat:format + shareContext:nullptr]; + + [format release]; + + return context; +} + already_AddRefed GLContextProviderCGL::CreateForWindow(nsIWidget *aWidget) { - GLContextCGL *shareContext = GetGlobalContextCGL(); + if (!sCGLLibrary.EnsureInitialized()) { + return nullptr; + } - NSOpenGLContext *context = [[NSOpenGLContext alloc] - initWithFormat:sCGLLibrary.PixelFormat() - shareContext:(shareContext ? shareContext->mContext : NULL)]; + const NSOpenGLPixelFormatAttribute* attribs; + if (sCGLLibrary.UseDoubleBufferedWindows()) { + attribs = kAttribs_doubleBuffered; + } else { + attribs = kAttribs_singleBuffered; + } + NSOpenGLContext* context = CreateWithFormat(attribs); if (!context) { return nullptr; } @@ -211,10 +234,13 @@ GLContextProviderCGL::CreateForWindow(nsIWidget *aWidget) [context setValues:&opaque forParameter:NSOpenGLCPSurfaceOpacity]; SurfaceCaps caps = SurfaceCaps::ForRGBA(); - nsRefPtr glContext = new GLContextCGL(caps, - shareContext, - context); + ContextProfile profile = ContextProfile::OpenGLCompatibility; + nsRefPtr glContext = new GLContextCGL(caps, context, false, + profile); + if (!glContext->Init()) { + glContext = nullptr; + [context release]; return nullptr; } @@ -222,49 +248,54 @@ GLContextProviderCGL::CreateForWindow(nsIWidget *aWidget) } static already_AddRefed -CreateOffscreenFBOContext(bool aShare = true) +CreateOffscreenFBOContext(bool requireCompatProfile) { if (!sCGLLibrary.EnsureInitialized()) { return nullptr; } - GLContextCGL *shareContext = aShare ? GetGlobalContextCGL() : nullptr; - if (aShare && !shareContext) { - // if there is no share context, then we can't use FBOs. - return nullptr; - } + ContextProfile profile; + NSOpenGLContext* context = nullptr; - NSOpenGLContext *context = [[NSOpenGLContext alloc] - initWithFormat:sCGLLibrary.PixelFormat() - shareContext:shareContext ? shareContext->GetNSOpenGLContext() : NULL]; + if (!requireCompatProfile) { + profile = ContextProfile::OpenGLCore; + context = CreateWithFormat(kAttribs_offscreen_coreProfile); + } + if (!context) { + profile = ContextProfile::OpenGLCompatibility; + context = CreateWithFormat(kAttribs_offscreen); + } if (!context) { return nullptr; } SurfaceCaps dummyCaps = SurfaceCaps::Any(); - nsRefPtr glContext = new GLContextCGL(dummyCaps, shareContext, context, true); + nsRefPtr glContext = new GLContextCGL(dummyCaps, context, + true, profile); return glContext.forget(); } already_AddRefed -GLContextProviderCGL::CreateHeadless() +GLContextProviderCGL::CreateHeadless(bool requireCompatProfile) { - nsRefPtr glContext = CreateOffscreenFBOContext(); - if (!glContext) + nsRefPtr gl; + gl = CreateOffscreenFBOContext(requireCompatProfile); + if (!gl) return nullptr; - if (!glContext->Init()) + if (!gl->Init()) return nullptr; - return glContext.forget(); + return gl.forget(); } already_AddRefed GLContextProviderCGL::CreateOffscreen(const gfxIntSize& size, - const SurfaceCaps& caps) + const SurfaceCaps& caps, + bool requireCompatProfile) { - nsRefPtr glContext = CreateHeadless(); + nsRefPtr glContext = CreateHeadless(requireCompatProfile); if (!glContext->InitOffscreen(ToIntSize(size), caps)) return nullptr; @@ -299,7 +330,7 @@ GLContextProviderCGL::GetGlobalContext() void GLContextProviderCGL::Shutdown() { - gGlobalContext = nullptr; + gGlobalContext = nullptr; } } /* namespace gl */ diff --git a/gfx/gl/GLContextProviderEGL.cpp b/gfx/gl/GLContextProviderEGL.cpp index 12c2068091db..b946167fa66b 100644 --- a/gfx/gl/GLContextProviderEGL.cpp +++ b/gfx/gl/GLContextProviderEGL.cpp @@ -878,7 +878,7 @@ GLContextEGL::CreateEGLPixmapOffscreenContext(const gfxIntSize& size) } already_AddRefed -GLContextProviderEGL::CreateHeadless() +GLContextProviderEGL::CreateHeadless(bool) { if (!sEGLLibrary.EnsureInitialized()) { return nullptr; @@ -897,9 +897,10 @@ GLContextProviderEGL::CreateHeadless() // often without the ability to texture from them directly. already_AddRefed GLContextProviderEGL::CreateOffscreen(const gfxIntSize& size, - const SurfaceCaps& caps) + const SurfaceCaps& caps, + bool requireCompatProfile) { - nsRefPtr glContext = CreateHeadless(); + nsRefPtr glContext = CreateHeadless(requireCompatProfile); if (!glContext) return nullptr; diff --git a/gfx/gl/GLContextProviderGLX.cpp b/gfx/gl/GLContextProviderGLX.cpp index 4587b7d2e1dd..22eab4603067 100644 --- a/gfx/gl/GLContextProviderGLX.cpp +++ b/gfx/gl/GLContextProviderGLX.cpp @@ -1213,7 +1213,7 @@ DONE_CREATING_PIXMAP: } already_AddRefed -GLContextProviderGLX::CreateHeadless() +GLContextProviderGLX::CreateHeadless(bool) { gfxIntSize dummySize = gfxIntSize(16, 16); nsRefPtr glContext = CreateOffscreenPixmapContext(dummySize); @@ -1225,9 +1225,10 @@ GLContextProviderGLX::CreateHeadless() already_AddRefed GLContextProviderGLX::CreateOffscreen(const gfxIntSize& size, - const SurfaceCaps& caps) + const SurfaceCaps& caps, + bool requireCompatProfile) { - nsRefPtr glContext = CreateHeadless(); + nsRefPtr glContext = CreateHeadless(requireCompatProfile); if (!glContext) return nullptr; diff --git a/gfx/gl/GLContextProviderImpl.h b/gfx/gl/GLContextProviderImpl.h index 6efc65de064f..9e87170c8237 100644 --- a/gfx/gl/GLContextProviderImpl.h +++ b/gfx/gl/GLContextProviderImpl.h @@ -58,11 +58,12 @@ public: */ static already_AddRefed CreateOffscreen(const gfxIntSize& size, - const SurfaceCaps& caps); + const SurfaceCaps& caps, + bool requireCompatProfile); // Just create a context. We'll add offscreen stuff ourselves. static already_AddRefed - CreateHeadless(); + CreateHeadless(bool requireCompatProfile); /** * Create wrapping Gecko GLContext for external gl context. diff --git a/gfx/gl/GLContextProviderNull.cpp b/gfx/gl/GLContextProviderNull.cpp index 61732a6e6b63..231c75be5f3f 100644 --- a/gfx/gl/GLContextProviderNull.cpp +++ b/gfx/gl/GLContextProviderNull.cpp @@ -22,13 +22,14 @@ GLContextProviderNull::CreateWrappingExisting(void*, void*) already_AddRefed GLContextProviderNull::CreateOffscreen(const gfxIntSize&, - const SurfaceCaps&) + const SurfaceCaps&, + bool) { return nullptr; } already_AddRefed -GLContextProviderNull::CreateHeadless() +GLContextProviderNull::CreateHeadless(bool) { return nullptr; } diff --git a/gfx/gl/GLContextProviderWGL.cpp b/gfx/gl/GLContextProviderWGL.cpp index a8c2124d6788..bf605c057e9a 100644 --- a/gfx/gl/GLContextProviderWGL.cpp +++ b/gfx/gl/GLContextProviderWGL.cpp @@ -607,7 +607,7 @@ CreateWindowOffscreenContext() } already_AddRefed -GLContextProviderWGL::CreateHeadless() +GLContextProviderWGL::CreateHeadless(bool) { if (!sWGLLib.EnsureInitialized()) { return nullptr; @@ -641,9 +641,10 @@ GLContextProviderWGL::CreateHeadless() already_AddRefed GLContextProviderWGL::CreateOffscreen(const gfxIntSize& size, - const SurfaceCaps& caps) + const SurfaceCaps& caps, + bool requireCompatProfile) { - nsRefPtr glContext = CreateHeadless(); + nsRefPtr glContext = CreateHeadless(requireCompatProfile); if (!glContext) return nullptr; diff --git a/gfx/gl/GLContextSymbols.h b/gfx/gl/GLContextSymbols.h index 3904beac1736..91ff5ac71dc9 100644 --- a/gfx/gl/GLContextSymbols.h +++ b/gfx/gl/GLContextSymbols.h @@ -666,6 +666,10 @@ struct GLContextSymbols GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data); PFNGLCOMPRESSEDTEXSUBIMAGE3D fCompressedTexSubImage3D; + + // get_string_indexed + typedef const GLubyte* (GLAPIENTRY * pfnGLGetStringiT)(GLenum name, GLuint index); + pfnGLGetStringiT fGetStringi; }; } diff --git a/gfx/gl/GLContextTypes.cpp b/gfx/gl/GLContextTypes.cpp index b11c99098d28..2cca59dc96aa 100644 --- a/gfx/gl/GLContextTypes.cpp +++ b/gfx/gl/GLContextTypes.cpp @@ -12,8 +12,3 @@ GLFormats::GLFormats() { std::memset(this, 0, sizeof(GLFormats)); } - -PixelBufferFormat::PixelBufferFormat() -{ - std::memset(this, 0, sizeof(PixelBufferFormat)); -} diff --git a/gfx/gl/GLContextTypes.h b/gfx/gl/GLContextTypes.h index f21cc11cf06e..979790bb1e58 100644 --- a/gfx/gl/GLContextTypes.h +++ b/gfx/gl/GLContextTypes.h @@ -43,19 +43,6 @@ struct GLFormats GLsizei samples; }; -struct PixelBufferFormat -{ - // Constructs a zeroed object: - PixelBufferFormat(); - - int red, green, blue; - int alpha; - int depth, stencil; - int samples; - - int ColorBits() const { return red + green + blue; } -}; - } /* namespace gl */ } /* namespace mozilla */ diff --git a/gfx/gl/GLLibraryEGL.cpp b/gfx/gl/GLLibraryEGL.cpp index a07b3e79f3df..40cee8d0c98d 100644 --- a/gfx/gl/GLLibraryEGL.cpp +++ b/gfx/gl/GLLibraryEGL.cpp @@ -35,8 +35,7 @@ static const char *sEGLExtensionNames[] = { "EGL_EXT_create_context_robustness", "EGL_KHR_image", "EGL_KHR_fence_sync", - "EGL_ANDROID_native_fence_sync", - nullptr + "EGL_ANDROID_native_fence_sync" }; #if defined(ANDROID) @@ -240,8 +239,8 @@ GLLibraryEGL::EnsureInitialized() }; // Do not warn about the failure to load this - see bug 1092191 - GLLibraryLoader::LoadSymbols(mEGLLibrary, &optionalSymbols[0], - nullptr, nullptr, false); + GLLibraryLoader::LoadSymbols(mEGLLibrary, &optionalSymbols[0], nullptr, nullptr, + false); #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 18 MOZ_RELEASE_ASSERT(mSymbols.fQueryStringImplementationANDROID, @@ -421,15 +420,24 @@ GLLibraryEGL::EnsureInitialized() void GLLibraryEGL::InitExtensions() { - const char *extensions = (const char*)fQueryString(mEGLDisplay, LOCAL_EGL_EXTENSIONS); + std::vector driverExtensionList; - if (!extensions) { + const char* rawExts = (const char*)fQueryString(mEGLDisplay, LOCAL_EGL_EXTENSIONS); + if (rawExts) { + nsDependentCString exts(rawExts); + SplitByChar(exts, ' ', &driverExtensionList); + } else { NS_WARNING("Failed to load EGL extension list!"); - return; } - GLContext::InitializeExtensionsBitSet(mAvailableExtensions, extensions, - sEGLExtensionNames); + const bool shouldDumpExts = GLContext::ShouldDumpExts(); + if (shouldDumpExts) { + printf_stderr("%i EGL driver extensions: (*: recognized)\n", + (uint32_t)driverExtensionList.size()); + } + + MarkBitfieldByStrings(driverExtensionList, shouldDumpExts, sEGLExtensionNames, + &mAvailableExtensions); } void diff --git a/gfx/gl/GLLibraryEGL.h b/gfx/gl/GLLibraryEGL.h index 1d175a217efe..4e055344c8f5 100644 --- a/gfx/gl/GLLibraryEGL.h +++ b/gfx/gl/GLLibraryEGL.h @@ -15,6 +15,7 @@ #include "GeckoProfiler.h" #include +#include #if defined(XP_WIN) diff --git a/gfx/layers/GLImages.cpp b/gfx/layers/GLImages.cpp index 66fa218df961..7525eefd40fa 100644 --- a/gfx/layers/GLImages.cpp +++ b/gfx/layers/GLImages.cpp @@ -39,7 +39,7 @@ GLImage::GetAsSourceSurface() MOZ_ASSERT(NS_IsMainThread(), "Should be on the main thread"); if (!sSnapshotContext) { - sSnapshotContext = GLContextProvider::CreateHeadless(); + sSnapshotContext = GLContextProvider::CreateHeadless(false); if (!sSnapshotContext) { NS_WARNING("Failed to create snapshot GLContext"); return nullptr; diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp index ec7a9f3325f4..4e8b7bd8c5b2 100644 --- a/gfx/layers/opengl/CompositorOGL.cpp +++ b/gfx/layers/opengl/CompositorOGL.cpp @@ -124,8 +124,11 @@ CompositorOGL::CreateContext() SurfaceCaps caps = SurfaceCaps::ForRGB(); caps.preserve = false; caps.bpp16 = gfxPlatform::GetPlatform()->GetOffscreenFormat() == gfxImageFormat::RGB16_565; + + bool requireCompatProfile = true; context = GLContextProvider::CreateOffscreen(gfxIntSize(mSurfaceSize.width, - mSurfaceSize.height), caps); + mSurfaceSize.height), + caps, requireCompatProfile); } if (!context) diff --git a/gfx/tests/gtest/TestCompositor.cpp b/gfx/tests/gtest/TestCompositor.cpp index a8cf3c2674b9..8d17c650d57e 100644 --- a/gfx/tests/gtest/TestCompositor.cpp +++ b/gfx/tests/gtest/TestCompositor.cpp @@ -45,7 +45,7 @@ public: caps.preserve = false; caps.bpp16 = false; nsRefPtr context = GLContextProvider::CreateOffscreen( - gfxIntSize(gCompWidth, gCompHeight), caps); + gfxIntSize(gCompWidth, gCompHeight), caps, true); return context.forget().take(); } return nullptr; diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp index 2e271cf3f52b..1394387fceba 100644 --- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -1099,8 +1099,9 @@ gfxPlatform::GetSkiaGLGlue() * FIXME: This should be stored in TLS or something, since there needs to be one for each thread using it. As it * stands, this only works on the main thread. */ - mozilla::gl::SurfaceCaps caps = mozilla::gl::SurfaceCaps::ForRGBA(); - nsRefPtr glContext = mozilla::gl::GLContextProvider::CreateOffscreen(gfxIntSize(16, 16), caps); + bool requireCompatProfile = true; + nsRefPtr glContext; + glContext = mozilla::gl::GLContextProvider::CreateHeadless(requireCompatProfile); if (!glContext) { printf_stderr("Failed to create GLContext for SkiaGL!\n"); return nullptr; diff --git a/widget/android/GfxInfo.cpp b/widget/android/GfxInfo.cpp index 4ab9da311ede..95bd0d409cd8 100644 --- a/widget/android/GfxInfo.cpp +++ b/widget/android/GfxInfo.cpp @@ -72,8 +72,8 @@ public: } nsRefPtr gl; - gl = gl::GLContextProvider::CreateOffscreen(gfxIntSize(16, 16), - gl::SurfaceCaps::ForRGB()); + bool requireCompatProfile = true; + gl = gl::GLContextProvider::CreateHeadless(requireCompatProfile); if (!gl) { // Setting mReady to true here means that we won't retry. Everything will From 36dcff0baf082b9888952c049714ab11ca435de5 Mon Sep 17 00:00:00 2001 From: Matt Woodrow Date: Thu, 5 Feb 2015 14:11:46 +1300 Subject: [PATCH 50/74] Bug 1114976 - Don't try to free TextureClients if allocation failed. r=nical --- gfx/layers/ipc/ImageBridgeChild.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gfx/layers/ipc/ImageBridgeChild.cpp b/gfx/layers/ipc/ImageBridgeChild.cpp index e41e7dab5f2a..a8f0af21bb81 100644 --- a/gfx/layers/ipc/ImageBridgeChild.cpp +++ b/gfx/layers/ipc/ImageBridgeChild.cpp @@ -389,6 +389,10 @@ static void ReleaseTextureClientNow(TextureClient* aClient) // static void ImageBridgeChild::DispatchReleaseTextureClient(TextureClient* aClient) { + if (!aClient) { + return; + } + if (!IsCreated()) { // TextureClient::Release should normally happen in the ImageBridgeChild // thread because it usually generate some IPDL messages. From 1bedd8d3d78e82fedacb1b7d740e5d0302233b05 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Wed, 4 Feb 2015 17:12:51 -0800 Subject: [PATCH 51/74] Bug 1129523 - Implement MediaPromise proxies. r=cpearce,r=mattwoodrow --- dom/media/MediaPromise.h | 106 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/dom/media/MediaPromise.h b/dom/media/MediaPromise.h index 628b0f85a648..da774c0451ce 100644 --- a/dom/media/MediaPromise.h +++ b/dom/media/MediaPromise.h @@ -537,6 +537,112 @@ private: nsRefPtr mConsumer; }; +// Proxy Media Calls. +// +// This machinery allows callers to schedule a promise-returning method to be +// invoked asynchronously on a given thread, while at the same time receiving +// a promise upon which to invoke Then() immediately. ProxyMediaCall dispatches +// a task to invoke the method on the proper thread and also chain the resulting +// promise to the one that the caller received, so that resolve/reject values +// are forwarded through. + +namespace detail { + +template +class MethodCallBase +{ +public: + MethodCallBase() { MOZ_COUNT_CTOR(MethodCallBase); } + virtual nsRefPtr Invoke() = 0; + virtual ~MethodCallBase() { MOZ_COUNT_DTOR(MethodCallBase); }; +}; + +template +class MethodCallWithNoArgs : public MethodCallBase +{ +public: + typedef nsRefPtr(ThisType::*Type)(); + MethodCallWithNoArgs(ThisType* aThisVal, Type aMethod) + : mThisVal(aThisVal), mMethod(aMethod) {} + nsRefPtr Invoke() MOZ_OVERRIDE { return ((*mThisVal).*mMethod)(); } +protected: + nsRefPtr mThisVal; + Type mMethod; +}; + +// NB: MethodCallWithOneArg definition should go here, if/when it is needed. + +template +class MethodCallWithTwoArgs : public MethodCallBase +{ +public: + typedef nsRefPtr(ThisType::*Type)(Arg1Type, Arg2Type); + MethodCallWithTwoArgs(ThisType* aThisVal, Type aMethod, Arg1Type aArg1, Arg2Type aArg2) + : mThisVal(aThisVal), mMethod(aMethod), mArg1(aArg1), mArg2(aArg2) {} + nsRefPtr Invoke() MOZ_OVERRIDE { return ((*mThisVal).*mMethod)(mArg1, mArg2); } +protected: + nsRefPtr mThisVal; + Type mMethod; + Arg1Type mArg1; + Arg2Type mArg2; +}; + +template +class ProxyRunnable : public nsRunnable +{ +public: + ProxyRunnable(PromiseType* aProxyPromise, MethodCallBase* aMethodCall) + : mProxyPromise(aProxyPromise), mMethodCall(aMethodCall) {} + + NS_IMETHODIMP Run() + { + nsRefPtr p = mMethodCall->Invoke(); + mMethodCall = nullptr; + p->ChainTo(mProxyPromise.forget(), ""); + return NS_OK; + } + +private: + nsRefPtr mProxyPromise; + nsAutoPtr> mMethodCall; +}; + +template +static nsRefPtr +ProxyInternal(TargetType* aTarget, MethodCallBase* aMethodCall, const char* aCallerName) +{ + nsRefPtr p = new PromiseType(aCallerName); + nsRefPtr> r = new ProxyRunnable(p, aMethodCall); + nsresult rv = detail::DispatchMediaPromiseRunnable(aTarget, r); + MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv)); + return p; +} + +} // namespace detail + +template +static nsRefPtr +ProxyMediaCall(TargetType* aTarget, ThisType* aThisVal, const char* aCallerName, + nsRefPtr(ThisType::*aMethod)()) +{ + typedef detail::MethodCallWithNoArgs MethodCallType; + MethodCallType* methodCall = new MethodCallType(aThisVal, aMethod); + return detail::ProxyInternal(aTarget, methodCall, aCallerName); +} + +// NB: One-arg overload should go here, if/when it is needed. + +template +static nsRefPtr +ProxyMediaCall(TargetType* aTarget, ThisType* aThisVal, const char* aCallerName, + nsRefPtr(ThisType::*aMethod)(Arg1Type, Arg2Type), Arg1Type aArg1, Arg2Type aArg2) +{ + typedef detail::MethodCallWithTwoArgs MethodCallType; + MethodCallType* methodCall = new MethodCallType(aThisVal, aMethod, aArg1, aArg2); + return detail::ProxyInternal(aTarget, methodCall, aCallerName); +} + #undef PROMISE_LOG } // namespace mozilla From a15ce311b87c6e72b9c4a943d2e1ed5fea2fc9e6 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Wed, 4 Feb 2015 17:12:51 -0800 Subject: [PATCH 52/74] Bug 1129523 - Use ProxyMediaCall for video decode tasks. r=cpearce,r=mattwoodrow --- dom/media/MediaDecoderStateMachine.cpp | 126 ++++++++----------------- dom/media/MediaDecoderStateMachine.h | 6 -- 2 files changed, 40 insertions(+), 92 deletions(-) diff --git a/dom/media/MediaDecoderStateMachine.cpp b/dom/media/MediaDecoderStateMachine.cpp index c15ef560d8af..142a66fe6156 100644 --- a/dom/media/MediaDecoderStateMachine.cpp +++ b/dom/media/MediaDecoderStateMachine.cpp @@ -657,42 +657,6 @@ MediaDecoderStateMachine::NeedToSkipToNextKeyframe() return false; } -void -MediaDecoderStateMachine::DecodeVideo() -{ - int64_t currentTime = 0; - bool skipToNextKeyFrame = false; - { - ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); - NS_ASSERTION(OnDecodeThread(), "Should be on decode thread."); - - if (mState != DECODER_STATE_DECODING && - mState != DECODER_STATE_DECODING_FIRSTFRAME && - mState != DECODER_STATE_BUFFERING && - mState != DECODER_STATE_SEEKING) { - mVideoRequestStatus = RequestStatus::Idle; - DispatchDecodeTasksIfNeeded(); - return; - } - - skipToNextKeyFrame = NeedToSkipToNextKeyframe(); - currentTime = mState == DECODER_STATE_SEEKING ? 0 : GetMediaTime(); - - // Time the video decode, so that if it's slow, we can increase our low - // audio threshold to reduce the chance of an audio underrun while we're - // waiting for a video decode to complete. - mVideoDecodeStartTime = TimeStamp::Now(); - } - - SAMPLE_LOG("DecodeVideo() queued=%i, decoder-queued=%o, skip=%i, time=%lld", - VideoQueue().GetSize(), mReader->SizeOfVideoQueueInFrames(), skipToNextKeyFrame, currentTime); - - mReader->RequestVideoData(skipToNextKeyFrame, currentTime) - ->Then(DecodeTaskQueue(), __func__, this, - &MediaDecoderStateMachine::OnVideoDecoded, - &MediaDecoderStateMachine::OnVideoNotDecoded); -} - bool MediaDecoderStateMachine::NeedToDecodeAudio() { @@ -711,32 +675,6 @@ MediaDecoderStateMachine::NeedToDecodeAudio() (mState != DECODER_STATE_SEEKING || mDecodeToSeekTarget))); } -void -MediaDecoderStateMachine::DecodeAudio() -{ - { - ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); - NS_ASSERTION(OnDecodeThread(), "Should be on decode thread."); - - if (mState != DECODER_STATE_DECODING && - mState != DECODER_STATE_DECODING_FIRSTFRAME && - mState != DECODER_STATE_BUFFERING && - mState != DECODER_STATE_SEEKING) { - mAudioRequestStatus = RequestStatus::Idle; - DispatchDecodeTasksIfNeeded(); - mon.NotifyAll(); - return; - } - } - - SAMPLE_LOG("DecodeAudio() queued=%i, decoder-queued=%o", - AudioQueue().GetSize(), mReader->SizeOfAudioQueueInFrames()); - - mReader->RequestAudioData()->Then(DecodeTaskQueue(), __func__, this, - &MediaDecoderStateMachine::OnAudioDecoded, - &MediaDecoderStateMachine::OnAudioNotDecoded); -} - bool MediaDecoderStateMachine::IsAudioSeekComplete() { @@ -1989,23 +1927,26 @@ MediaDecoderStateMachine::EnsureAudioDecodeTaskQueued() SAMPLE_LOG("EnsureAudioDecodeTaskQueued isDecoding=%d status=%d", IsAudioDecoding(), mAudioRequestStatus); - if (mState >= DECODER_STATE_COMPLETED || mState == DECODER_STATE_DORMANT) { + if (mState != DECODER_STATE_DECODING && + mState != DECODER_STATE_DECODING_FIRSTFRAME && + mState != DECODER_STATE_BUFFERING && + mState != DECODER_STATE_SEEKING) { return NS_OK; } - MOZ_ASSERT(mState >= DECODER_STATE_DECODING_FIRSTFRAME); - - if (IsAudioDecoding() && mAudioRequestStatus == RequestStatus::Idle && !mWaitingForDecoderSeek) { - RefPtr task( - NS_NewRunnableMethod(this, &MediaDecoderStateMachine::DecodeAudio)); - nsresult rv = DecodeTaskQueue()->Dispatch(task); - if (NS_SUCCEEDED(rv)) { - mAudioRequestStatus = RequestStatus::Pending; - } else { - DECODER_WARN("Failed to dispatch task to decode audio"); - } + if (!IsAudioDecoding() || mAudioRequestStatus != RequestStatus::Idle || mWaitingForDecoderSeek) { + return NS_OK; } + SAMPLE_LOG("Queueing audio task - queued=%i, decoder-queued=%o", + AudioQueue().GetSize(), mReader->SizeOfAudioQueueInFrames()); + + mAudioRequestStatus = RequestStatus::Pending; + ProxyMediaCall(DecodeTaskQueue(), mReader.get(), __func__, &MediaDecoderReader::RequestAudioData) + ->Then(DecodeTaskQueue(), __func__, this, + &MediaDecoderStateMachine::OnAudioDecoded, + &MediaDecoderStateMachine::OnAudioNotDecoded); + return NS_OK; } @@ -2034,23 +1975,36 @@ MediaDecoderStateMachine::EnsureVideoDecodeTaskQueued() NS_ASSERTION(OnStateMachineThread() || OnDecodeThread(), "Should be on state machine or decode thread."); - if (mState >= DECODER_STATE_COMPLETED || mState == DECODER_STATE_DORMANT) { + if (mState != DECODER_STATE_DECODING && + mState != DECODER_STATE_DECODING_FIRSTFRAME && + mState != DECODER_STATE_BUFFERING && + mState != DECODER_STATE_SEEKING) { return NS_OK; } - MOZ_ASSERT(mState >= DECODER_STATE_DECODING_FIRSTFRAME); - - if (IsVideoDecoding() && mVideoRequestStatus == RequestStatus::Idle && !mWaitingForDecoderSeek) { - RefPtr task( - NS_NewRunnableMethod(this, &MediaDecoderStateMachine::DecodeVideo)); - nsresult rv = DecodeTaskQueue()->Dispatch(task); - if (NS_SUCCEEDED(rv)) { - mVideoRequestStatus = RequestStatus::Pending; - } else { - DECODER_WARN("Failed to dispatch task to decode video"); - } + if (!IsVideoDecoding() || mVideoRequestStatus != RequestStatus::Idle || mWaitingForDecoderSeek) { + return NS_OK; } + bool skipToNextKeyFrame = NeedToSkipToNextKeyframe(); + int64_t currentTime = mState == DECODER_STATE_SEEKING ? 0 : GetMediaTime(); + + // Time the video decode, so that if it's slow, we can increase our low + // audio threshold to reduce the chance of an audio underrun while we're + // waiting for a video decode to complete. + mVideoDecodeStartTime = TimeStamp::Now(); + + SAMPLE_LOG("Queueing video task - queued=%i, decoder-queued=%o, skip=%i, time=%lld", + VideoQueue().GetSize(), mReader->SizeOfVideoQueueInFrames(), skipToNextKeyFrame, + currentTime); + + mVideoRequestStatus = RequestStatus::Pending; + ProxyMediaCall(DecodeTaskQueue(), mReader.get(), __func__, + &MediaDecoderReader::RequestVideoData, skipToNextKeyFrame, currentTime) + ->Then(DecodeTaskQueue(), __func__, this, + &MediaDecoderStateMachine::OnVideoDecoded, + &MediaDecoderStateMachine::OnVideoNotDecoded); + return NS_OK; } diff --git a/dom/media/MediaDecoderStateMachine.h b/dom/media/MediaDecoderStateMachine.h index 0ad8144a5dec..2707a4fa4f4e 100644 --- a/dom/media/MediaDecoderStateMachine.h +++ b/dom/media/MediaDecoderStateMachine.h @@ -489,16 +489,10 @@ protected: // decode more. bool NeedToDecodeAudio(); - // Decodes some audio. This should be run on the decode task queue. - void DecodeAudio(); - // True if our buffers of decoded video are not full, and we should // decode more. bool NeedToDecodeVideo(); - // Decodes some video. This should be run on the decode task queue. - void DecodeVideo(); - // Returns true if we've got less than aAudioUsecs microseconds of decoded // and playable data. The decoder monitor must be held. // From 6e2bccf8bb289c325e548aee8cb5f09ca6d7b225 Mon Sep 17 00:00:00 2001 From: Matthew Gregan Date: Mon, 2 Feb 2015 21:49:00 +1300 Subject: [PATCH 53/74] Bug 1121258 - Add a GMP PDM to allow MP4 playback via OpenH264. r=cpearce --- dom/media/MediaInfo.h | 19 +- dom/media/fmp4/MP4Decoder.cpp | 7 + dom/media/fmp4/PlatformDecoderModule.cpp | 9 + dom/media/fmp4/PlatformDecoderModule.h | 1 + dom/media/fmp4/gmp/GMPAudioDecoder.cpp | 224 +++++++++++++++++ dom/media/fmp4/gmp/GMPAudioDecoder.h | 89 +++++++ dom/media/fmp4/gmp/GMPDecoderModule.cpp | 91 +++++++ dom/media/fmp4/gmp/GMPDecoderModule.h | 42 ++++ dom/media/fmp4/gmp/GMPVideoDecoder.cpp | 245 +++++++++++++++++++ dom/media/fmp4/gmp/GMPVideoDecoder.h | 105 ++++++++ dom/media/fmp4/gmp/MediaDataDecoderProxy.cpp | 101 ++++++++ dom/media/fmp4/gmp/MediaDataDecoderProxy.h | 191 +++++++++++++++ dom/media/fmp4/gmp/moz.build | 26 ++ dom/media/fmp4/moz.build | 2 + modules/libpref/init/all.js | 1 + 15 files changed, 1149 insertions(+), 4 deletions(-) create mode 100644 dom/media/fmp4/gmp/GMPAudioDecoder.cpp create mode 100644 dom/media/fmp4/gmp/GMPAudioDecoder.h create mode 100644 dom/media/fmp4/gmp/GMPDecoderModule.cpp create mode 100644 dom/media/fmp4/gmp/GMPDecoderModule.h create mode 100644 dom/media/fmp4/gmp/GMPVideoDecoder.cpp create mode 100644 dom/media/fmp4/gmp/GMPVideoDecoder.h create mode 100644 dom/media/fmp4/gmp/MediaDataDecoderProxy.cpp create mode 100644 dom/media/fmp4/gmp/MediaDataDecoderProxy.h create mode 100644 dom/media/fmp4/gmp/moz.build diff --git a/dom/media/MediaInfo.h b/dom/media/MediaInfo.h index 37a280c43edc..aad07ff05329 100644 --- a/dom/media/MediaInfo.h +++ b/dom/media/MediaInfo.h @@ -36,12 +36,18 @@ struct TrackInfo { // Stores info relevant to presenting media frames. class VideoInfo { +private: + VideoInfo(int32_t aWidth, int32_t aHeight, bool aHasVideo) + : mDisplay(aWidth, aHeight) + , mStereoMode(StereoMode::MONO) + , mHasVideo(aHasVideo) + , mIsHardwareAccelerated(false) + { + } + public: VideoInfo() - : mDisplay(0,0) - , mStereoMode(StereoMode::MONO) - , mHasVideo(false) - , mIsHardwareAccelerated(false) + : VideoInfo(0, 0, false) { // TODO: TrackInfo should be initialized by its specific codec decoder. // This following call should be removed once we have that implemented. @@ -49,6 +55,11 @@ public: EmptyString(), EmptyString(), true); } + VideoInfo(int32_t aWidth, int32_t aHeight) + : VideoInfo(aWidth, aHeight, true) + { + } + // Size in pixels at which the video is rendered. This is after it has // been scaled by its aspect ratio. nsIntSize mDisplay; diff --git a/dom/media/fmp4/MP4Decoder.cpp b/dom/media/fmp4/MP4Decoder.cpp index ba7a2ac275aa..2e8d0dc29fda 100644 --- a/dom/media/fmp4/MP4Decoder.cpp +++ b/dom/media/fmp4/MP4Decoder.cpp @@ -212,6 +212,12 @@ IsGonkMP4DecoderAvailable() return Preferences::GetBool("media.fragmented-mp4.gonk.enabled", false); } +static bool +IsGMPDecoderAvailable() +{ + return Preferences::GetBool("media.fragmented-mp4.gmp.enabled", false); +} + static bool HavePlatformMPEGDecoders() { @@ -224,6 +230,7 @@ HavePlatformMPEGDecoders() IsFFmpegAvailable() || IsAppleAvailable() || IsGonkMP4DecoderAvailable() || + IsGMPDecoderAvailable() || // TODO: Other platforms... false; } diff --git a/dom/media/fmp4/PlatformDecoderModule.cpp b/dom/media/fmp4/PlatformDecoderModule.cpp index 2c857958d9e2..a20365179f6e 100644 --- a/dom/media/fmp4/PlatformDecoderModule.cpp +++ b/dom/media/fmp4/PlatformDecoderModule.cpp @@ -22,6 +22,7 @@ #ifdef MOZ_WIDGET_ANDROID #include "AndroidDecoderModule.h" #endif +#include "GMPDecoderModule.h" #include "mozilla/Preferences.h" #ifdef MOZ_EME @@ -40,6 +41,7 @@ bool PlatformDecoderModule::sFFmpegDecoderEnabled = false; bool PlatformDecoderModule::sGonkDecoderEnabled = false; bool PlatformDecoderModule::sAndroidMCDecoderEnabled = false; bool PlatformDecoderModule::sAndroidMCDecoderPreferred = false; +bool PlatformDecoderModule::sGMPDecoderEnabled = false; /* static */ void @@ -68,6 +70,9 @@ PlatformDecoderModule::Init() "media.fragmented-mp4.android-media-codec.preferred", false); #endif + Preferences::AddBoolVarCache(&sGMPDecoderEnabled, + "media.fragmented-mp4.gmp.enabled", false); + #ifdef XP_WIN WMFDecoderModule::Init(); #endif @@ -167,6 +172,10 @@ PlatformDecoderModule::CreatePDM() return m.forget(); } #endif + if (sGMPDecoderEnabled) { + nsRefPtr m(new AVCCDecoderModule(new GMPDecoderModule())); + return m.forget(); + } return nullptr; } diff --git a/dom/media/fmp4/PlatformDecoderModule.h b/dom/media/fmp4/PlatformDecoderModule.h index 0f5366c53449..52624de286bd 100644 --- a/dom/media/fmp4/PlatformDecoderModule.h +++ b/dom/media/fmp4/PlatformDecoderModule.h @@ -145,6 +145,7 @@ protected: static bool sGonkDecoderEnabled; static bool sAndroidMCDecoderPreferred; static bool sAndroidMCDecoderEnabled; + static bool sGMPDecoderEnabled; }; // A callback used by MediaDataDecoder to return output/errors to the diff --git a/dom/media/fmp4/gmp/GMPAudioDecoder.cpp b/dom/media/fmp4/gmp/GMPAudioDecoder.cpp new file mode 100644 index 000000000000..98c65c627625 --- /dev/null +++ b/dom/media/fmp4/gmp/GMPAudioDecoder.cpp @@ -0,0 +1,224 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* 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 "GMPAudioDecoder.h" + +namespace mozilla { + +#if defined(DEBUG) +static bool IsOnGMPThread() +{ + nsCOMPtr mps = do_GetService("@mozilla.org/gecko-media-plugin-service;1"); + MOZ_ASSERT(mps); + + nsCOMPtr gmpThread; + nsresult rv = mps->GetThread(getter_AddRefs(gmpThread)); + MOZ_ASSERT(NS_SUCCEEDED(rv) && gmpThread); + return NS_GetCurrentThread() == gmpThread; +} +#endif + +void +AudioCallbackAdapter::Decoded(const nsTArray& aPCM, uint64_t aTimeStamp, uint32_t aChannels, uint32_t aRate) +{ + MOZ_ASSERT(IsOnGMPThread()); + + if (aRate == 0 || aChannels == 0) { + NS_WARNING("Invalid rate or num channels returned on GMP audio samples"); + mCallback->Error(); + return; + } + + size_t numFrames = aPCM.Length() / aChannels; + MOZ_ASSERT((aPCM.Length() % aChannels) == 0); + nsAutoArrayPtr audioData(new AudioDataValue[aPCM.Length()]); + + for (size_t i = 0; i < aPCM.Length(); ++i) { + audioData[i] = AudioSampleToFloat(aPCM[i]); + } + + if (mMustRecaptureAudioPosition) { + mAudioFrameSum = 0; + auto timestamp = UsecsToFrames(aTimeStamp, aRate); + if (!timestamp.isValid()) { + NS_WARNING("Invalid timestamp"); + mCallback->Error(); + return; + } + mAudioFrameOffset = timestamp.value(); + MOZ_ASSERT(mAudioFrameOffset >= 0); + mMustRecaptureAudioPosition = false; + } + + auto timestamp = FramesToUsecs(mAudioFrameOffset + mAudioFrameSum, aRate); + if (!timestamp.isValid()) { + NS_WARNING("Invalid timestamp on audio samples"); + mCallback->Error(); + return; + } + mAudioFrameSum += numFrames; + + auto duration = FramesToUsecs(numFrames, aRate); + if (!duration.isValid()) { + NS_WARNING("Invalid duration on audio samples"); + mCallback->Error(); + return; + } + + nsRefPtr audio(new AudioData(mLastStreamOffset, + timestamp.value(), + duration.value(), + numFrames, + audioData.forget(), + aChannels, + aRate)); + +#ifdef LOG_SAMPLE_DECODE + LOG("Decoded audio sample! timestamp=%lld duration=%lld currentLength=%u", + timestamp, duration, currentLength); +#endif + + mCallback->Output(audio); +} + +void +AudioCallbackAdapter::InputDataExhausted() +{ + MOZ_ASSERT(IsOnGMPThread()); + mCallback->InputExhausted(); +} + +void +AudioCallbackAdapter::DrainComplete() +{ + MOZ_ASSERT(IsOnGMPThread()); + mCallback->DrainComplete(); +} + +void +AudioCallbackAdapter::ResetComplete() +{ + MOZ_ASSERT(IsOnGMPThread()); + mMustRecaptureAudioPosition = true; + mCallback->FlushComplete(); +} + +void +AudioCallbackAdapter::Error(GMPErr aErr) +{ + MOZ_ASSERT(IsOnGMPThread()); + mCallback->Error(); +} + +void +AudioCallbackAdapter::Terminated() +{ + NS_WARNING("AAC GMP decoder terminated."); + mCallback->Error(); +} + +void +GMPAudioDecoder::InitTags(nsTArray& aTags) +{ + aTags.AppendElement(NS_LITERAL_CSTRING("aac")); +} + +nsCString +GMPAudioDecoder::GetNodeId() +{ + return NS_LITERAL_CSTRING(""); +} + +nsresult +GMPAudioDecoder::Init() +{ + MOZ_ASSERT(IsOnGMPThread()); + + mMPS = do_GetService("@mozilla.org/gecko-media-plugin-service;1"); + MOZ_ASSERT(mMPS); + + nsTArray tags; + InitTags(tags); + nsresult rv = mMPS->GetGMPAudioDecoder(&tags, GetNodeId(), &mGMP); + NS_ENSURE_SUCCESS(rv, rv); + MOZ_ASSERT(mGMP); + + nsTArray codecSpecific; + codecSpecific.AppendElements(mConfig.audio_specific_config->Elements(), + mConfig.audio_specific_config->Length()); + + rv = mGMP->InitDecode(kGMPAudioCodecAAC, + mConfig.channel_count, + mConfig.bits_per_sample, + mConfig.samples_per_second, + codecSpecific, + mAdapter); + NS_ENSURE_SUCCESS(rv, rv); + + return NS_OK; +} + +nsresult +GMPAudioDecoder::Input(mp4_demuxer::MP4Sample* aSample) +{ + MOZ_ASSERT(IsOnGMPThread()); + + nsAutoPtr sample(aSample); + if (!mGMP) { + mCallback->Error(); + return NS_ERROR_FAILURE; + } + + mAdapter->SetLastStreamOffset(sample->byte_offset); + + gmp::GMPAudioSamplesImpl samples(sample, mConfig.channel_count, mConfig.samples_per_second); + nsresult rv = mGMP->Decode(samples); + if (NS_FAILED(rv)) { + mCallback->Error(); + return rv; + } + + return NS_OK; +} + +nsresult +GMPAudioDecoder::Flush() +{ + MOZ_ASSERT(IsOnGMPThread()); + + if (!mGMP || NS_FAILED(mGMP->Reset())) { + // Abort the flush. + mCallback->FlushComplete(); + } + + return NS_OK; +} + +nsresult +GMPAudioDecoder::Drain() +{ + MOZ_ASSERT(IsOnGMPThread()); + + if (!mGMP || NS_FAILED(mGMP->Drain())) { + mCallback->DrainComplete(); + } + + return NS_OK; +} + +nsresult +GMPAudioDecoder::Shutdown() +{ + if (!mGMP) { + return NS_ERROR_FAILURE; + } + mGMP->Close(); + mGMP = nullptr; + + return NS_OK; +} + +} // namespace mozilla diff --git a/dom/media/fmp4/gmp/GMPAudioDecoder.h b/dom/media/fmp4/gmp/GMPAudioDecoder.h new file mode 100644 index 000000000000..3e17bb15c6aa --- /dev/null +++ b/dom/media/fmp4/gmp/GMPAudioDecoder.h @@ -0,0 +1,89 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* 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/. */ + +#if !defined(GMPAudioDecoder_h_) +#define GMPAudioDecoder_h_ + +#include "GMPAudioDecoderProxy.h" +#include "MediaDataDecoderProxy.h" +#include "PlatformDecoderModule.h" +#include "mozIGeckoMediaPluginService.h" + +namespace mozilla { + +class AudioCallbackAdapter : public GMPAudioDecoderCallbackProxy { +public: + explicit AudioCallbackAdapter(MediaDataDecoderCallbackProxy* aCallback) + : mCallback(aCallback) + , mLastStreamOffset(0) + , mAudioFrameSum(0) + , mAudioFrameOffset(0) + , mMustRecaptureAudioPosition(true) + {} + + // GMPAudioDecoderCallbackProxy + virtual void Decoded(const nsTArray& aPCM, uint64_t aTimeStamp, uint32_t aChannels, uint32_t aRate) MOZ_OVERRIDE; + virtual void InputDataExhausted() MOZ_OVERRIDE; + virtual void DrainComplete() MOZ_OVERRIDE; + virtual void ResetComplete() MOZ_OVERRIDE; + virtual void Error(GMPErr aErr) MOZ_OVERRIDE; + virtual void Terminated() MOZ_OVERRIDE; + + void SetLastStreamOffset(int64_t aStreamOffset) { + mLastStreamOffset = aStreamOffset; + } + +private: + MediaDataDecoderCallbackProxy* mCallback; + int64_t mLastStreamOffset; + + int64_t mAudioFrameSum; + int64_t mAudioFrameOffset; + bool mMustRecaptureAudioPosition; +}; + +class GMPAudioDecoder : public MediaDataDecoder { +protected: + GMPAudioDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig, + MediaTaskQueue* aTaskQueue, + MediaDataDecoderCallbackProxy* aCallback, + AudioCallbackAdapter* aAdapter) + : mConfig(aConfig) + , mCallback(aCallback) + , mGMP(nullptr) + , mAdapter(aAdapter) + { + } + +public: + GMPAudioDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig, + MediaTaskQueue* aTaskQueue, + MediaDataDecoderCallbackProxy* aCallback) + : GMPAudioDecoder(aConfig, aTaskQueue, aCallback, new AudioCallbackAdapter(aCallback)) + { + } + + virtual nsresult Init() MOZ_OVERRIDE; + virtual nsresult Input(mp4_demuxer::MP4Sample* aSample) MOZ_OVERRIDE; + virtual nsresult Flush() MOZ_OVERRIDE; + virtual nsresult Drain() MOZ_OVERRIDE; + virtual nsresult Shutdown() MOZ_OVERRIDE; + +protected: + virtual void InitTags(nsTArray& aTags); + virtual nsCString GetNodeId(); + +private: + const mp4_demuxer::AudioDecoderConfig& mConfig; + MediaDataDecoderCallbackProxy* mCallback; + nsCOMPtr mMPS; + GMPAudioDecoderProxy* mGMP; + nsAutoPtr mAdapter; +}; + +} // namespace mozilla + +#endif // GMPAudioDecoder_h_ diff --git a/dom/media/fmp4/gmp/GMPDecoderModule.cpp b/dom/media/fmp4/gmp/GMPDecoderModule.cpp new file mode 100644 index 000000000000..ccfaf6b4b508 --- /dev/null +++ b/dom/media/fmp4/gmp/GMPDecoderModule.cpp @@ -0,0 +1,91 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* 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 "GMPDecoderModule.h" +#include "GMPAudioDecoder.h" +#include "GMPVideoDecoder.h" +#include "MediaDataDecoderProxy.h" +#include "mozIGeckoMediaPluginService.h" +#include "nsServiceManagerUtils.h" + +namespace mozilla { + +GMPDecoderModule::GMPDecoderModule() +{ +} + +GMPDecoderModule::~GMPDecoderModule() +{ +} + +nsresult +GMPDecoderModule::Shutdown() +{ + return NS_OK; +} + +static already_AddRefed +CreateDecoderWrapper(MediaDataDecoderCallback* aCallback) +{ + nsCOMPtr gmpService = do_GetService("@mozilla.org/gecko-media-plugin-service;1"); + if (!gmpService) { + return nullptr; + } + + nsCOMPtr thread; + nsresult rv = gmpService->GetThread(getter_AddRefs(thread)); + if (NS_FAILED(rv)) { + return nullptr; + } + + nsRefPtr decoder(new MediaDataDecoderProxy(thread, aCallback)); + return decoder.forget(); +} + +already_AddRefed +GMPDecoderModule::CreateVideoDecoder(const mp4_demuxer::VideoDecoderConfig& aConfig, + layers::LayersBackend aLayersBackend, + layers::ImageContainer* aImageContainer, + MediaTaskQueue* aVideoTaskQueue, + MediaDataDecoderCallback* aCallback) +{ + if (strcmp(aConfig.mime_type, "video/avc") != 0) { + return nullptr; + } + + nsRefPtr wrapper = CreateDecoderWrapper(aCallback); + wrapper->SetProxyTarget(new GMPVideoDecoder(aConfig, + aLayersBackend, + aImageContainer, + aVideoTaskQueue, + wrapper->Callback())); + return wrapper.forget(); +} + +already_AddRefed +GMPDecoderModule::CreateAudioDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig, + MediaTaskQueue* aAudioTaskQueue, + MediaDataDecoderCallback* aCallback) +{ + if (strcmp(aConfig.mime_type, "audio/mp4a-latm") != 0) { + return nullptr; + } + + nsRefPtr wrapper = CreateDecoderWrapper(aCallback); + wrapper->SetProxyTarget(new GMPAudioDecoder(aConfig, + aAudioTaskQueue, + wrapper->Callback())); + return wrapper.forget(); +} + +bool +GMPDecoderModule::DecoderNeedsAVCC(const mp4_demuxer::VideoDecoderConfig& aConfig) +{ + // GMPVideoCodecType::kGMPVideoCodecH264 specifies that encoded frames must be in AVCC format. + return true; +} + +} // namespace mozilla diff --git a/dom/media/fmp4/gmp/GMPDecoderModule.h b/dom/media/fmp4/gmp/GMPDecoderModule.h new file mode 100644 index 000000000000..82819993b4a6 --- /dev/null +++ b/dom/media/fmp4/gmp/GMPDecoderModule.h @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* 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/. */ + +#if !defined(GMPDecoderModule_h_) +#define GMPDecoderModule_h_ + +#include "PlatformDecoderModule.h" + +namespace mozilla { + +class GMPDecoderModule : public PlatformDecoderModule { +public: + GMPDecoderModule(); + + virtual ~GMPDecoderModule(); + + // Called when the decoders have shutdown. Main thread only. + virtual nsresult Shutdown() MOZ_OVERRIDE; + + // Decode thread. + virtual already_AddRefed + CreateVideoDecoder(const mp4_demuxer::VideoDecoderConfig& aConfig, + layers::LayersBackend aLayersBackend, + layers::ImageContainer* aImageContainer, + MediaTaskQueue* aVideoTaskQueue, + MediaDataDecoderCallback* aCallback) MOZ_OVERRIDE; + + // Decode thread. + virtual already_AddRefed + CreateAudioDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig, + MediaTaskQueue* aAudioTaskQueue, + MediaDataDecoderCallback* aCallback) MOZ_OVERRIDE; + + virtual bool DecoderNeedsAVCC(const mp4_demuxer::VideoDecoderConfig& aConfig) MOZ_OVERRIDE; +}; + +} // namespace mozilla + +#endif // GMPDecoderModule_h_ diff --git a/dom/media/fmp4/gmp/GMPVideoDecoder.cpp b/dom/media/fmp4/gmp/GMPVideoDecoder.cpp new file mode 100644 index 000000000000..d764055eab9a --- /dev/null +++ b/dom/media/fmp4/gmp/GMPVideoDecoder.cpp @@ -0,0 +1,245 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* 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 "GMPVideoDecoder.h" +#include "GMPVideoHost.h" +#include "prsystem.h" + +namespace mozilla { + +#if defined(DEBUG) +static bool IsOnGMPThread(); +#endif + +void +VideoCallbackAdapter::Decoded(GMPVideoi420Frame* aDecodedFrame) +{ + GMPUniquePtr decodedFrame(aDecodedFrame); + + MOZ_ASSERT(IsOnGMPThread()); + + VideoData::YCbCrBuffer b; + for (int i = 0; i < kGMPNumOfPlanes; ++i) { + b.mPlanes[i].mData = decodedFrame->Buffer(GMPPlaneType(i)); + b.mPlanes[i].mStride = decodedFrame->Stride(GMPPlaneType(i)); + if (i == kGMPYPlane) { + b.mPlanes[i].mWidth = decodedFrame->Width(); + b.mPlanes[i].mHeight = decodedFrame->Height(); + } else { + b.mPlanes[i].mWidth = (decodedFrame->Width() + 1) / 2; + b.mPlanes[i].mHeight = (decodedFrame->Height() + 1) / 2; + } + b.mPlanes[i].mOffset = 0; + b.mPlanes[i].mSkip = 0; + } + + gfx::IntRect pictureRegion(0, 0, decodedFrame->Width(), decodedFrame->Height()); + nsRefPtr v = VideoData::Create(mVideoInfo, + mImageContainer, + mLastStreamOffset, + decodedFrame->Timestamp(), + decodedFrame->Duration(), + b, + false, + -1, + pictureRegion); + if (v) { + mCallback->Output(v); + } else { + mCallback->Error(); + } +} + +void +VideoCallbackAdapter::ReceivedDecodedReferenceFrame(const uint64_t aPictureId) +{ + MOZ_ASSERT(IsOnGMPThread()); +} + +void +VideoCallbackAdapter::ReceivedDecodedFrame(const uint64_t aPictureId) +{ + MOZ_ASSERT(IsOnGMPThread()); +} + +void +VideoCallbackAdapter::InputDataExhausted() +{ + MOZ_ASSERT(IsOnGMPThread()); + mCallback->InputExhausted(); +} + +void +VideoCallbackAdapter::DrainComplete() +{ + MOZ_ASSERT(IsOnGMPThread()); + mCallback->DrainComplete(); +} + +void +VideoCallbackAdapter::ResetComplete() +{ + MOZ_ASSERT(IsOnGMPThread()); + mCallback->FlushComplete(); +} + +void +VideoCallbackAdapter::Error(GMPErr aErr) +{ + MOZ_ASSERT(IsOnGMPThread()); + mCallback->Error(); +} + +void +VideoCallbackAdapter::Terminated() +{ + // Note that this *may* be called from the proxy thread also. + NS_WARNING("H.264 GMP decoder terminated."); + mCallback->Error(); +} + +void +GMPVideoDecoder::InitTags(nsTArray& aTags) +{ + aTags.AppendElement(NS_LITERAL_CSTRING("h264")); +} + +nsCString +GMPVideoDecoder::GetNodeId() +{ + return NS_LITERAL_CSTRING(""); +} + +GMPUniquePtr +GMPVideoDecoder::CreateFrame(mp4_demuxer::MP4Sample* aSample) +{ + GMPVideoFrame* ftmp = nullptr; + GMPErr err = mHost->CreateFrame(kGMPEncodedVideoFrame, &ftmp); + if (GMP_FAILED(err)) { + mCallback->Error(); + return nullptr; + } + + GMPUniquePtr frame(static_cast(ftmp)); + err = frame->CreateEmptyFrame(aSample->size); + if (GMP_FAILED(err)) { + mCallback->Error(); + return nullptr; + } + + memcpy(frame->Buffer(), aSample->data, frame->Size()); + + frame->SetEncodedWidth(mConfig.display_width); + frame->SetEncodedHeight(mConfig.display_height); + frame->SetTimeStamp(aSample->composition_timestamp); + frame->SetCompleteFrame(true); + frame->SetDuration(aSample->duration); + frame->SetFrameType(aSample->is_sync_point ? kGMPKeyFrame : kGMPDeltaFrame); + frame->SetBufferType(GMP_BufferLength32); + + return frame; +} + +nsresult +GMPVideoDecoder::Init() +{ + MOZ_ASSERT(IsOnGMPThread()); + + mMPS = do_GetService("@mozilla.org/gecko-media-plugin-service;1"); + MOZ_ASSERT(mMPS); + + nsTArray tags; + InitTags(tags); + nsresult rv = mMPS->GetGMPVideoDecoder(&tags, GetNodeId(), &mHost, &mGMP); + NS_ENSURE_SUCCESS(rv, rv); + MOZ_ASSERT(mHost && mGMP); + + GMPVideoCodec codec; + memset(&codec, 0, sizeof(codec)); + + codec.mGMPApiVersion = kGMPVersion33; + + codec.mCodecType = kGMPVideoCodecH264; + codec.mWidth = mConfig.display_width; + codec.mHeight = mConfig.display_height; + + nsTArray codecSpecific; + codecSpecific.AppendElement(0); // mPacketizationMode. + codecSpecific.AppendElements(mConfig.extra_data->Elements(), + mConfig.extra_data->Length()); + + rv = mGMP->InitDecode(codec, + codecSpecific, + mAdapter, + PR_GetNumberOfProcessors()); + NS_ENSURE_SUCCESS(rv, rv); + + return NS_OK; +} + +nsresult +GMPVideoDecoder::Input(mp4_demuxer::MP4Sample* aSample) +{ + MOZ_ASSERT(IsOnGMPThread()); + + nsAutoPtr sample(aSample); + if (!mGMP) { + mCallback->Error(); + return NS_ERROR_FAILURE; + } + + mAdapter->SetLastStreamOffset(sample->byte_offset); + + GMPUniquePtr frame = CreateFrame(sample); + nsTArray info; // No codec specific per-frame info to pass. + nsresult rv = mGMP->Decode(Move(frame), false, info, 0); + if (NS_FAILED(rv)) { + mCallback->Error(); + return rv; + } + + return NS_OK; +} + +nsresult +GMPVideoDecoder::Flush() +{ + MOZ_ASSERT(IsOnGMPThread()); + + if (!mGMP || NS_FAILED(mGMP->Reset())) { + // Abort the flush. + mCallback->FlushComplete(); + } + + return NS_OK; +} + +nsresult +GMPVideoDecoder::Drain() +{ + MOZ_ASSERT(IsOnGMPThread()); + + if (!mGMP || NS_FAILED(mGMP->Drain())) { + mCallback->DrainComplete(); + } + + return NS_OK; +} + +nsresult +GMPVideoDecoder::Shutdown() +{ + // Note that this *may* be called from the proxy thread also. + if (!mGMP) { + return NS_ERROR_FAILURE; + } + mGMP->Close(); + mGMP = nullptr; + + return NS_OK; +} + +} // namespace mozilla diff --git a/dom/media/fmp4/gmp/GMPVideoDecoder.h b/dom/media/fmp4/gmp/GMPVideoDecoder.h new file mode 100644 index 000000000000..f95f24444fca --- /dev/null +++ b/dom/media/fmp4/gmp/GMPVideoDecoder.h @@ -0,0 +1,105 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* 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/. */ + +#if !defined(GMPVideoDecoder_h_) +#define GMPVideoDecoder_h_ + +#include "GMPVideoDecoderProxy.h" +#include "ImageContainer.h" +#include "MediaDataDecoderProxy.h" +#include "PlatformDecoderModule.h" +#include "mozIGeckoMediaPluginService.h" +#include "mp4_demuxer/DecoderData.h" + +namespace mozilla { + +class VideoCallbackAdapter : public GMPVideoDecoderCallbackProxy { +public: + VideoCallbackAdapter(MediaDataDecoderCallbackProxy* aCallback, + VideoInfo aVideoInfo, + layers::ImageContainer* aImageContainer) + : mCallback(aCallback) + , mLastStreamOffset(0) + , mVideoInfo(aVideoInfo) + , mImageContainer(aImageContainer) + {} + + // GMPVideoDecoderCallbackProxy + virtual void Decoded(GMPVideoi420Frame* aDecodedFrame) MOZ_OVERRIDE; + virtual void ReceivedDecodedReferenceFrame(const uint64_t aPictureId) MOZ_OVERRIDE; + virtual void ReceivedDecodedFrame(const uint64_t aPictureId) MOZ_OVERRIDE; + virtual void InputDataExhausted() MOZ_OVERRIDE; + virtual void DrainComplete() MOZ_OVERRIDE; + virtual void ResetComplete() MOZ_OVERRIDE; + virtual void Error(GMPErr aErr) MOZ_OVERRIDE; + virtual void Terminated() MOZ_OVERRIDE; + + void SetLastStreamOffset(int64_t aStreamOffset) { + mLastStreamOffset = aStreamOffset; + } + +private: + MediaDataDecoderCallbackProxy* mCallback; + int64_t mLastStreamOffset; + + VideoInfo mVideoInfo; + nsRefPtr mImageContainer; +}; + +class GMPVideoDecoder : public MediaDataDecoder { +protected: + GMPVideoDecoder(const mp4_demuxer::VideoDecoderConfig& aConfig, + layers::LayersBackend aLayersBackend, + layers::ImageContainer* aImageContainer, + MediaTaskQueue* aTaskQueue, + MediaDataDecoderCallbackProxy* aCallback, + VideoCallbackAdapter* aAdapter) + : mConfig(aConfig) + , mCallback(aCallback) + , mGMP(nullptr) + , mHost(nullptr) + , mAdapter(aAdapter) + { + } + +public: + GMPVideoDecoder(const mp4_demuxer::VideoDecoderConfig& aConfig, + layers::LayersBackend aLayersBackend, + layers::ImageContainer* aImageContainer, + MediaTaskQueue* aTaskQueue, + MediaDataDecoderCallbackProxy* aCallback) + : GMPVideoDecoder(aConfig, aLayersBackend, aImageContainer, aTaskQueue, aCallback, + new VideoCallbackAdapter(aCallback, + VideoInfo(aConfig.display_width, + aConfig.display_height), + aImageContainer)) + { + } + + virtual nsresult Init() MOZ_OVERRIDE; + virtual nsresult Input(mp4_demuxer::MP4Sample* aSample) MOZ_OVERRIDE; + virtual nsresult Flush() MOZ_OVERRIDE; + virtual nsresult Drain() MOZ_OVERRIDE; + virtual nsresult Shutdown() MOZ_OVERRIDE; + +protected: + virtual void InitTags(nsTArray& aTags); + virtual nsCString GetNodeId(); + virtual GMPUniquePtr CreateFrame(mp4_demuxer::MP4Sample* aSample); + +private: + const mp4_demuxer::VideoDecoderConfig& mConfig; + MediaDataDecoderCallbackProxy* mCallback; + nsCOMPtr mMPS; + GMPVideoDecoderProxy* mGMP; + GMPVideoHost* mHost; + nsAutoPtr mAdapter; +}; + + +} // namespace mozilla + +#endif // GMPVideoDecoder_h_ diff --git a/dom/media/fmp4/gmp/MediaDataDecoderProxy.cpp b/dom/media/fmp4/gmp/MediaDataDecoderProxy.cpp new file mode 100644 index 000000000000..24a1558b2e5d --- /dev/null +++ b/dom/media/fmp4/gmp/MediaDataDecoderProxy.cpp @@ -0,0 +1,101 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* 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 "MediaDataDecoderProxy.h" + +namespace mozilla { + +void +MediaDataDecoderCallbackProxy::Error() +{ + mProxyCallback->Error(); + mProxyDecoder->Shutdown(); +} + +void +MediaDataDecoderCallbackProxy::FlushComplete() +{ + mProxyDecoder->FlushComplete(); +} + +nsresult +MediaDataDecoderProxy::Init() +{ + MOZ_ASSERT(!mIsShutdown); + nsRefPtr task(new InitTask(mProxyDecoder)); + nsresult rv = mProxyThread->Dispatch(task, NS_DISPATCH_SYNC); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_SUCCESS(task->Result(), task->Result()); + + return NS_OK; +} + +nsresult +MediaDataDecoderProxy::Input(mp4_demuxer::MP4Sample* aSample) +{ + MOZ_ASSERT(!IsOnProxyThread()); + MOZ_ASSERT(!mIsShutdown); + + nsRefPtr task(new InputTask(mProxyDecoder, aSample)); + nsresult rv = mProxyThread->Dispatch(task, NS_DISPATCH_NORMAL); + NS_ENSURE_SUCCESS(rv, rv); + + return NS_OK; +} + +nsresult +MediaDataDecoderProxy::Flush() +{ + MOZ_ASSERT(!IsOnProxyThread()); + MOZ_ASSERT(!mIsShutdown); + + mFlushComplete.Set(false); + + nsRefPtr task; + task = NS_NewRunnableMethod(mProxyDecoder, &MediaDataDecoder::Flush); + nsresult rv = mProxyThread->Dispatch(task, NS_DISPATCH_NORMAL); + NS_ENSURE_SUCCESS(rv, rv); + + mFlushComplete.WaitUntil(true); + + return NS_OK; +} + +nsresult +MediaDataDecoderProxy::Drain() +{ + MOZ_ASSERT(!IsOnProxyThread()); + MOZ_ASSERT(!mIsShutdown); + + nsRefPtr task; + task = NS_NewRunnableMethod(mProxyDecoder, &MediaDataDecoder::Drain); + nsresult rv = mProxyThread->Dispatch(task, NS_DISPATCH_NORMAL); + NS_ENSURE_SUCCESS(rv, rv); + return NS_OK; +} + +nsresult +MediaDataDecoderProxy::Shutdown() +{ + // Note that this *may* be called from the proxy thread also. + MOZ_ASSERT(!mIsShutdown); +#if defined(DEBUG) + mIsShutdown = true; +#endif + nsRefPtr task; + task = NS_NewRunnableMethod(mProxyDecoder, &MediaDataDecoder::Shutdown); + nsresult rv = mProxyThread->Dispatch(task, NS_DISPATCH_SYNC); + NS_ENSURE_SUCCESS(rv, rv); + return NS_OK; +} + +void +MediaDataDecoderProxy::FlushComplete() +{ + mFlushComplete.Set(true); +} + +} // namespace mozilla diff --git a/dom/media/fmp4/gmp/MediaDataDecoderProxy.h b/dom/media/fmp4/gmp/MediaDataDecoderProxy.h new file mode 100644 index 000000000000..bc93af17ef81 --- /dev/null +++ b/dom/media/fmp4/gmp/MediaDataDecoderProxy.h @@ -0,0 +1,191 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* 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/. */ + +#if !defined(MediaDataDecoderProxy_h_) +#define MediaDataDecoderProxy_h_ + +#include "PlatformDecoderModule.h" +#include "mp4_demuxer/DecoderData.h" +#include "nsAutoPtr.h" +#include "nsRefPtr.h" +#include "nsThreadUtils.h" +#include "nscore.h" + +namespace mozilla { + +class InputTask : public nsRunnable { +public: + InputTask(MediaDataDecoder* aDecoder, + mp4_demuxer::MP4Sample* aSample) + : mDecoder(aDecoder) + , mSample(aSample) + {} + + NS_IMETHOD Run() { + mDecoder->Input(mSample.forget()); + return NS_OK; + } + +private: + nsRefPtr mDecoder; + nsAutoPtr mSample; +}; + +class InitTask : public nsRunnable { +public: + explicit InitTask(MediaDataDecoder* aDecoder) + : mDecoder(aDecoder) + , mResultValid(false) + {} + + NS_IMETHOD Run() { + mResult = mDecoder->Init(); + mResultValid = true; + return NS_OK; + } + + nsresult Result() { + MOZ_ASSERT(mResultValid); + return mResult; + } + +private: + MediaDataDecoder* mDecoder; + nsresult mResult; + bool mResultValid; +}; + +template +class Condition { +public: + explicit Condition(T aValue) + : mMonitor("Condition") + , mCondition(aValue) + {} + + void Set(T aValue) { + MonitorAutoLock mon(mMonitor); + mCondition = aValue; + mon.NotifyAll(); + } + + void WaitUntil(T aValue) { + MonitorAutoLock mon(mMonitor); + while (mCondition != aValue) { + mon.Wait(); + } + } + +private: + Monitor mMonitor; + T mCondition; +}; + +class MediaDataDecoderProxy; + +class MediaDataDecoderCallbackProxy : public MediaDataDecoderCallback { +public: + explicit MediaDataDecoderCallbackProxy(MediaDataDecoderProxy* aProxyDecoder, MediaDataDecoderCallback* aCallback) + : mProxyDecoder(aProxyDecoder) + , mProxyCallback(aCallback) + { + } + + virtual void Output(MediaData* aData) MOZ_OVERRIDE { + mProxyCallback->Output(aData); + } + + virtual void Error() MOZ_OVERRIDE; + + virtual void InputExhausted() MOZ_OVERRIDE { + mProxyCallback->InputExhausted(); + } + + virtual void DrainComplete() MOZ_OVERRIDE { + mProxyCallback->DrainComplete(); + } + + virtual void NotifyResourcesStatusChanged() MOZ_OVERRIDE { + mProxyCallback->NotifyResourcesStatusChanged(); + } + + virtual void ReleaseMediaResources() MOZ_OVERRIDE { + mProxyCallback->ReleaseMediaResources(); + } + + virtual void FlushComplete(); + +private: + MediaDataDecoderProxy* mProxyDecoder; + MediaDataDecoderCallback* mProxyCallback; +}; + +class MediaDataDecoderProxy : public MediaDataDecoder { +public: + MediaDataDecoderProxy(nsIThread* aProxyThread, MediaDataDecoderCallback* aCallback) + : mProxyThread(aProxyThread) + , mProxyCallback(this, aCallback) + , mFlushComplete(false) +#if defined(DEBUG) + , mIsShutdown(false) +#endif + { + } + + // Ideally, this would return a regular MediaDataDecoderCallback pointer + // to retain the clean abstraction, but until MediaDataDecoderCallback + // supports the FlushComplete interface, this will have to do. When MDDC + // supports FlushComplete, this, the GMP*Decoders, and the + // *CallbackAdapters can be reverted to accepting a regular + // MediaDataDecoderCallback pointer. + MediaDataDecoderCallbackProxy* Callback() + { + return &mProxyCallback; + } + + void SetProxyTarget(MediaDataDecoder* aProxyDecoder) + { + MOZ_ASSERT(aProxyDecoder); + mProxyDecoder = aProxyDecoder; + } + + // These are called from the decoder thread pool. + // Init and Shutdown run synchronously on the proxy thread, all others are + // asynchronously and responded to via the MediaDataDecoderCallback. + // Note: the nsresults returned by the proxied decoder are lost. + virtual nsresult Init() MOZ_OVERRIDE; + virtual nsresult Input(mp4_demuxer::MP4Sample* aSample) MOZ_OVERRIDE; + virtual nsresult Flush() MOZ_OVERRIDE; + virtual nsresult Drain() MOZ_OVERRIDE; + virtual nsresult Shutdown() MOZ_OVERRIDE; + + // Called by MediaDataDecoderCallbackProxy. + void FlushComplete(); + +private: +#ifdef DEBUG + bool IsOnProxyThread() { + return NS_GetCurrentThread() == mProxyThread; + } +#endif + + friend class InputTask; + friend class InitTask; + + nsRefPtr mProxyDecoder; + nsCOMPtr mProxyThread; + + MediaDataDecoderCallbackProxy mProxyCallback; + + Condition mFlushComplete; +#if defined(DEBUG) + bool mIsShutdown; +#endif +}; + +} // namespace mozilla + +#endif // MediaDataDecoderProxy_h_ diff --git a/dom/media/fmp4/gmp/moz.build b/dom/media/fmp4/gmp/moz.build new file mode 100644 index 000000000000..8678834f9e04 --- /dev/null +++ b/dom/media/fmp4/gmp/moz.build @@ -0,0 +1,26 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +EXPORTS += [ + 'GMPAudioDecoder.h', + 'GMPDecoderModule.h', + 'GMPVideoDecoder.h', + 'MediaDataDecoderProxy.h', +] + +UNIFIED_SOURCES += [ + 'GMPAudioDecoder.cpp', + 'GMPDecoderModule.cpp', + 'GMPVideoDecoder.cpp', + 'MediaDataDecoderProxy.cpp', +] + +# GMPVideoEncodedFrameImpl.h needs IPC +include('/ipc/chromium/chromium-config.mozbuild') + +FINAL_LIBRARY = 'xul' + +FAIL_ON_WARNINGS = True diff --git a/dom/media/fmp4/moz.build b/dom/media/fmp4/moz.build index 4c52952ce605..2b74fad737c9 100644 --- a/dom/media/fmp4/moz.build +++ b/dom/media/fmp4/moz.build @@ -26,6 +26,8 @@ SOURCES += [ 'MP4Reader.cpp', ] +DIRS += ['gmp'] + if CONFIG['MOZ_WMF']: DIRS += [ 'wmf' ]; diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 52371321cc63..1511f7ffa82a 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -280,6 +280,7 @@ pref("media.directshow.enabled", true); #ifdef MOZ_FMP4 pref("media.fragmented-mp4.enabled", true); pref("media.fragmented-mp4.ffmpeg.enabled", false); +pref("media.fragmented-mp4.gmp.enabled", false); #if defined(XP_WIN) && defined(MOZ_WMF) || defined(XP_MACOSX) || defined(MOZ_WIDGET_GONK) // Denotes that the fragmented MP4 parser can be created by