merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2015-01-13 14:24:21 +01:00
commit f3a2dc46bd
166 changed files with 2219 additions and 1454 deletions

View File

@ -11,6 +11,7 @@
#include "mozilla/a11y/DocManager.h"
#include "mozilla/a11y/FocusManager.h"
#include "mozilla/a11y/SelectionManager.h"
#include "mozilla/Preferences.h"
#include "nsIObserver.h"
@ -254,7 +255,8 @@ IPCAccessibilityActive()
#ifdef MOZ_B2G
return false;
#else
return XRE_GetProcessType() == GeckoProcessType_Content;
return XRE_GetProcessType() == GeckoProcessType_Content &&
mozilla::Preferences::GetBool("accessibility.ipc_architecture.enabled", true);
#endif
}

View File

@ -1095,9 +1095,6 @@ var gBrowserInit = {
socialBrowser.addEventListener("MozApplicationManifest",
OfflineApps, false);
let uriToLoad = this._getUriToLoad();
var isLoadingBlank = isBlankPageURL(uriToLoad);
// This pageshow listener needs to be registered before we may call
// swapBrowsersAndCloseOther() to receive pageshow events fired by that.
let mm = window.messageManager;
@ -1135,6 +1132,7 @@ var gBrowserInit = {
SessionStore.reviveCrashedTab(tab);
}, false, true);
let uriToLoad = this._getUriToLoad();
if (uriToLoad && uriToLoad != "about:blank") {
if (uriToLoad instanceof Ci.nsISupportsArray) {
let count = uriToLoad.Count();
@ -1219,8 +1217,10 @@ var gBrowserInit = {
UpdateUrlbarSearchSplitterState();
if (!isLoadingBlank || !focusAndSelectUrlBar())
if (!(isBlankPageURL(uriToLoad) || uriToLoad == "about:privatebrowsing") ||
!focusAndSelectUrlBar()) {
gBrowser.selectedBrowser.focus();
}
// Set up Sanitize Item
this._initializeSanitizer();

View File

@ -29,13 +29,8 @@ function test() {
// Open a newtab after setting the custom newtab url
openNewTab(aWindow, function () {
if (aIsPrivateMode) {
is(aWindow.gBrowser.selectedBrowser.currentURI.spec, newTabURL,
"URL of NewTab should always be " + newTabURL + " in " + mode + " mode");
} else {
is(aWindow.gBrowser.selectedBrowser.currentURI.spec, testURL,
"URL of NewTab should be the custom url");
}
is(aWindow.gBrowser.selectedBrowser.currentURI.spec, testURL,
"URL of NewTab should be the custom url");
// clear the custom url preference
Services.prefs.clearUserPref(newTabPrefName);

View File

@ -14,7 +14,8 @@ XPCOMUtils.defineLazyGetter(this, "BROWSER_NEW_TAB_URL", function () {
function getNewTabPageURL() {
if (PrivateBrowsingUtils.isWindowPrivate(window) &&
!PrivateBrowsingUtils.permanentPrivateBrowsing) {
!PrivateBrowsingUtils.permanentPrivateBrowsing &&
!Services.prefs.prefHasUserValue(PREF)) {
return "about:privatebrowsing";
}

View File

@ -473,8 +473,13 @@ class ShutdownLeaks(object):
for url, count in self._zipLeakedWindows(test["leakedWindows"]):
self.logger.warning("TEST-UNEXPECTED-FAIL | %s | leaked %d window(s) until shutdown [url = %s]" % (test["fileName"], count, url))
if test["leakedWindowsString"]:
self.logger.info("TEST-INFO | %s | windows(s) leaked: %s" % (test["fileName"], test["leakedWindowsString"]))
if test["leakedDocShells"]:
self.logger.warning("TEST-UNEXPECTED-FAIL | %s | leaked %d docShell(s) until shutdown" % (test["fileName"], len(test["leakedDocShells"])))
self.logger.info("TEST-INFO | %s | docShell(s) leaked: %s" % (test["fileName"],
', '.join(["[pid = %s] [id = %s]" % x for x in test["leakedDocShells"]])))
def _logWindow(self, line):
created = line[:2] == "++"
@ -486,7 +491,7 @@ class ShutdownLeaks(object):
self.logger.warning("TEST-UNEXPECTED-FAIL | ShutdownLeaks | failed to parse line <%s>" % line)
return
key = pid + "." + serial
key = (pid, serial)
if self.currentTest:
windows = self.currentTest["windows"]
@ -507,7 +512,7 @@ class ShutdownLeaks(object):
self.logger.warning("TEST-UNEXPECTED-FAIL | ShutdownLeaks | failed to parse line <%s>" % line)
return
key = pid + "." + id
key = (pid, id)
if self.currentTest:
docShells = self.currentTest["docShells"]
@ -528,7 +533,9 @@ class ShutdownLeaks(object):
leakingTests = []
for test in self.tests:
test["leakedWindows"] = [self.leakedWindows[id] for id in test["windows"] if id in self.leakedWindows]
leakedWindows = [id for id in test["windows"] if id in self.leakedWindows]
test["leakedWindows"] = [self.leakedWindows[id] for id in leakedWindows]
test["leakedWindowsString"] = ', '.join(["[pid = %s] [serial = %s]" % x for x in leakedWindows])
test["leakedDocShells"] = [id for id in test["docShells"] if id in self.leakedDocShells]
test["leakCount"] = len(test["leakedWindows"]) + len(test["leakedDocShells"])

View File

@ -31,8 +31,8 @@ public:
NS_DECL_NSIURI
// nsISizeOf
virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
explicit nsNullPrincipalURI(const nsCString &aSpec);

View File

@ -49,25 +49,25 @@ class nsPrincipal MOZ_FINAL : public nsBasePrincipal
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSISERIALIZABLE
NS_IMETHOD Equals(nsIPrincipal* other, bool* _retval);
NS_IMETHOD EqualsConsideringDomain(nsIPrincipal* other, bool* _retval);
NS_IMETHOD GetHashValue(uint32_t* aHashValue);
NS_IMETHOD GetURI(nsIURI** aURI);
NS_IMETHOD GetDomain(nsIURI** aDomain);
NS_IMETHOD SetDomain(nsIURI* aDomain);
NS_IMETHOD GetOrigin(char** aOrigin);
NS_IMETHOD Subsumes(nsIPrincipal* other, bool* _retval);
NS_IMETHOD SubsumesConsideringDomain(nsIPrincipal* other, bool* _retval);
NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report, bool allowIfInheritsPrincipal);
NS_IMETHOD GetJarPrefix(nsACString& aJarPrefix);
NS_IMETHOD GetAppStatus(uint16_t* aAppStatus);
NS_IMETHOD GetAppId(uint32_t* aAppStatus);
NS_IMETHOD GetIsInBrowserElement(bool* aIsInBrowserElement);
NS_IMETHOD GetUnknownAppId(bool* aUnknownAppId);
NS_IMETHOD GetIsNullPrincipal(bool* aIsNullPrincipal);
NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain);
NS_IMETHOD Equals(nsIPrincipal* other, bool* _retval) MOZ_OVERRIDE;
NS_IMETHOD EqualsConsideringDomain(nsIPrincipal* other, bool* _retval) MOZ_OVERRIDE;
NS_IMETHOD GetHashValue(uint32_t* aHashValue) MOZ_OVERRIDE;
NS_IMETHOD GetURI(nsIURI** aURI) MOZ_OVERRIDE;
NS_IMETHOD GetDomain(nsIURI** aDomain) MOZ_OVERRIDE;
NS_IMETHOD SetDomain(nsIURI* aDomain) MOZ_OVERRIDE;
NS_IMETHOD GetOrigin(char** aOrigin) MOZ_OVERRIDE;
NS_IMETHOD Subsumes(nsIPrincipal* other, bool* _retval) MOZ_OVERRIDE;
NS_IMETHOD SubsumesConsideringDomain(nsIPrincipal* other, bool* _retval) MOZ_OVERRIDE;
NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report, bool allowIfInheritsPrincipal) MOZ_OVERRIDE;
NS_IMETHOD GetJarPrefix(nsACString& aJarPrefix) MOZ_OVERRIDE;
NS_IMETHOD GetAppStatus(uint16_t* aAppStatus) MOZ_OVERRIDE;
NS_IMETHOD GetAppId(uint32_t* aAppStatus) MOZ_OVERRIDE;
NS_IMETHOD GetIsInBrowserElement(bool* aIsInBrowserElement) MOZ_OVERRIDE;
NS_IMETHOD GetUnknownAppId(bool* aUnknownAppId) MOZ_OVERRIDE;
NS_IMETHOD GetIsNullPrincipal(bool* aIsNullPrincipal) MOZ_OVERRIDE;
NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) MOZ_OVERRIDE;
#ifdef DEBUG
virtual void dumpImpl();
virtual void dumpImpl() MOZ_OVERRIDE;
#endif
nsPrincipal();
@ -132,25 +132,25 @@ public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIEXPANDEDPRINCIPAL
NS_DECL_NSISERIALIZABLE
NS_IMETHOD Equals(nsIPrincipal* other, bool* _retval);
NS_IMETHOD EqualsConsideringDomain(nsIPrincipal* other, bool* _retval);
NS_IMETHOD GetHashValue(uint32_t* aHashValue);
NS_IMETHOD GetURI(nsIURI** aURI);
NS_IMETHOD GetDomain(nsIURI** aDomain);
NS_IMETHOD SetDomain(nsIURI* aDomain);
NS_IMETHOD GetOrigin(char** aOrigin);
NS_IMETHOD Subsumes(nsIPrincipal* other, bool* _retval);
NS_IMETHOD SubsumesConsideringDomain(nsIPrincipal* other, bool* _retval);
NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report, bool allowIfInheritsPrincipal);
NS_IMETHOD GetJarPrefix(nsACString& aJarPrefix);
NS_IMETHOD GetAppStatus(uint16_t* aAppStatus);
NS_IMETHOD GetAppId(uint32_t* aAppStatus);
NS_IMETHOD GetIsInBrowserElement(bool* aIsInBrowserElement);
NS_IMETHOD GetUnknownAppId(bool* aUnknownAppId);
NS_IMETHOD GetIsNullPrincipal(bool* aIsNullPrincipal);
NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain);
NS_IMETHOD Equals(nsIPrincipal* other, bool* _retval) MOZ_OVERRIDE;
NS_IMETHOD EqualsConsideringDomain(nsIPrincipal* other, bool* _retval) MOZ_OVERRIDE;
NS_IMETHOD GetHashValue(uint32_t* aHashValue) MOZ_OVERRIDE;
NS_IMETHOD GetURI(nsIURI** aURI) MOZ_OVERRIDE;
NS_IMETHOD GetDomain(nsIURI** aDomain) MOZ_OVERRIDE;
NS_IMETHOD SetDomain(nsIURI* aDomain) MOZ_OVERRIDE;
NS_IMETHOD GetOrigin(char** aOrigin) MOZ_OVERRIDE;
NS_IMETHOD Subsumes(nsIPrincipal* other, bool* _retval) MOZ_OVERRIDE;
NS_IMETHOD SubsumesConsideringDomain(nsIPrincipal* other, bool* _retval) MOZ_OVERRIDE;
NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report, bool allowIfInheritsPrincipal) MOZ_OVERRIDE;
NS_IMETHOD GetJarPrefix(nsACString& aJarPrefix) MOZ_OVERRIDE;
NS_IMETHOD GetAppStatus(uint16_t* aAppStatus) MOZ_OVERRIDE;
NS_IMETHOD GetAppId(uint32_t* aAppStatus) MOZ_OVERRIDE;
NS_IMETHOD GetIsInBrowserElement(bool* aIsInBrowserElement) MOZ_OVERRIDE;
NS_IMETHOD GetUnknownAppId(bool* aUnknownAppId) MOZ_OVERRIDE;
NS_IMETHOD GetIsNullPrincipal(bool* aIsNullPrincipal) MOZ_OVERRIDE;
NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) MOZ_OVERRIDE;
#ifdef DEBUG
virtual void dumpImpl();
virtual void dumpImpl() MOZ_OVERRIDE;
#endif
virtual void GetScriptLocation(nsACString &aStr) MOZ_OVERRIDE;

View File

@ -47,16 +47,16 @@ public:
NS_DECL_ISUPPORTS
// nsIXULChromeRegistry methods:
NS_IMETHOD ReloadChrome();
NS_IMETHOD RefreshSkins();
NS_IMETHOD ReloadChrome() MOZ_OVERRIDE;
NS_IMETHOD RefreshSkins() MOZ_OVERRIDE;
NS_IMETHOD AllowScriptsForPackage(nsIURI* url,
bool* _retval);
bool* _retval) MOZ_OVERRIDE;
NS_IMETHOD AllowContentToAccess(nsIURI* url,
bool* _retval);
bool* _retval) MOZ_OVERRIDE;
// nsIChromeRegistry methods:
NS_IMETHOD_(bool) WrappersEnabled(nsIURI *aURI);
NS_IMETHOD ConvertChromeURL(nsIURI* aChromeURI, nsIURI* *aResult);
NS_IMETHOD_(bool) WrappersEnabled(nsIURI *aURI) MOZ_OVERRIDE;
NS_IMETHOD ConvertChromeURL(nsIURI* aChromeURI, nsIURI* *aResult) MOZ_OVERRIDE;
// nsChromeRegistry methods:
nsChromeRegistry() : mInitialized(false) { }

View File

@ -167,25 +167,25 @@ class nsChromeRegistryChrome : public nsChromeRegistry
virtual void ManifestContent(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
bool contentaccessible) MOZ_OVERRIDE;
virtual void ManifestLocale(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
bool contentaccessible) MOZ_OVERRIDE;
virtual void ManifestSkin(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
bool contentaccessible) MOZ_OVERRIDE;
virtual void ManifestOverlay(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
bool contentaccessible) MOZ_OVERRIDE;
virtual void ManifestStyle(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
bool contentaccessible) MOZ_OVERRIDE;
virtual void ManifestOverride(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
bool contentaccessible) MOZ_OVERRIDE;
virtual void ManifestResource(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
bool contentaccessible) MOZ_OVERRIDE;
};
#endif // nsChromeRegistryChrome_h

View File

@ -66,25 +66,25 @@ class nsChromeRegistryContent : public nsChromeRegistry
virtual void ManifestContent(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
bool contentaccessible) MOZ_OVERRIDE;
virtual void ManifestLocale(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
bool contentaccessible) MOZ_OVERRIDE;
virtual void ManifestSkin(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
bool contentaccessible) MOZ_OVERRIDE;
virtual void ManifestOverlay(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
bool contentaccessible) MOZ_OVERRIDE;
virtual void ManifestStyle(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
bool contentaccessible) MOZ_OVERRIDE;
virtual void ManifestOverride(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
bool contentaccessible) MOZ_OVERRIDE;
virtual void ManifestResource(ManifestProcessingContext& cx, int lineno,
char *const * argv, bool platform,
bool contentaccessible);
bool contentaccessible) MOZ_OVERRIDE;
};
#endif // nsChromeRegistryContent_h

View File

@ -132,14 +132,14 @@ NS_DEFINE_STATIC_IID_ACCESSOR(IHistory, IHISTORY_IID)
#define NS_DECL_IHISTORY \
NS_IMETHOD RegisterVisitedCallback(nsIURI *aURI, \
mozilla::dom::Link *aContent); \
mozilla::dom::Link *aContent) MOZ_OVERRIDE; \
NS_IMETHOD UnregisterVisitedCallback(nsIURI *aURI, \
mozilla::dom::Link *aContent); \
mozilla::dom::Link *aContent) MOZ_OVERRIDE; \
NS_IMETHOD VisitURI(nsIURI *aURI, \
nsIURI *aLastVisitedURI, \
uint32_t aFlags); \
NS_IMETHOD SetURITitle(nsIURI* aURI, const nsAString& aTitle); \
NS_IMETHOD NotifyVisited(nsIURI* aURI);
uint32_t aFlags) MOZ_OVERRIDE; \
NS_IMETHOD SetURITitle(nsIURI* aURI, const nsAString& aTitle) MOZ_OVERRIDE; \
NS_IMETHOD NotifyVisited(nsIURI* aURI) MOZ_OVERRIDE;
} // namespace mozilla

View File

@ -103,14 +103,14 @@ public:
return mAgent->SetVisibilityState(visible);
}
NS_IMETHODIMP CanPlayChanged(int32_t canPlay)
NS_IMETHODIMP CanPlayChanged(int32_t canPlay) MOZ_OVERRIDE
{
mCanPlay = static_cast<AudioChannelState>(canPlay);
mWaitCallback = false;
return NS_OK;
}
NS_IMETHODIMP WindowVolumeChanged()
NS_IMETHODIMP WindowVolumeChanged() MOZ_OVERRIDE
{
return NS_OK;
}

View File

@ -441,8 +441,10 @@ Link::GetHash(nsAString &_hash, ErrorResult& aError)
nsAutoCString ref;
nsresult rv = uri->GetRef(ref);
if (NS_SUCCEEDED(rv) && !ref.IsEmpty()) {
NS_UnescapeURL(ref); // XXX may result in random non-ASCII bytes!
_hash.Assign(char16_t('#'));
if (nsContentUtils::EncodeDecodeURLHash()) {
NS_UnescapeURL(ref); // XXX may result in random non-ASCII bytes!
}
AppendUTF8toUTF16(ref, _hash);
}
}

View File

@ -514,8 +514,10 @@ URL::GetHash(nsString& aHash, ErrorResult& aRv) const
nsAutoCString ref;
nsresult rv = mURI->GetRef(ref);
if (NS_SUCCEEDED(rv) && !ref.IsEmpty()) {
NS_UnescapeURL(ref); // XXX may result in random non-ASCII bytes!
aHash.Assign(char16_t('#'));
if (nsContentUtils::EncodeDecodeURLHash()) {
NS_UnescapeURL(ref); // XXX may result in random non-ASCII bytes!
}
AppendUTF8toUTF16(ref, aHash);
}
}

View File

@ -243,6 +243,7 @@ bool nsContentUtils::sFullscreenApiIsContentOnly = false;
bool nsContentUtils::sIsPerformanceTimingEnabled = false;
bool nsContentUtils::sIsResourceTimingEnabled = false;
bool nsContentUtils::sIsExperimentalAutocompleteEnabled = false;
bool nsContentUtils::sEncodeDecodeURLHash = false;
uint32_t nsContentUtils::sHandlingInputTimeout = 1000;
@ -520,6 +521,9 @@ nsContentUtils::Init()
Preferences::AddBoolVarCache(&sIsExperimentalAutocompleteEnabled,
"dom.forms.autocomplete.experimental", false);
Preferences::AddBoolVarCache(&sEncodeDecodeURLHash,
"dom.url.encode_decode_hash", false);
Preferences::AddUintVarCache(&sHandlingInputTimeout,
"dom.event.handling-user-input-time-limit",
1000);

View File

@ -1860,6 +1860,15 @@ public:
return sIsResourceTimingEnabled;
}
/*
* Returns true if URL setters should percent encode the Hash/Ref segment
* and getters should return the percent decoded value of the segment
*/
static bool EncodeDecodeURLHash()
{
return sEncodeDecodeURLHash;
}
/**
* Returns true if the doc tree branch which contains aDoc contains any
* plugins which we don't control event dispatch for, i.e. do any plugins
@ -2323,6 +2332,7 @@ private:
static bool sIsPerformanceTimingEnabled;
static bool sIsResourceTimingEnabled;
static bool sIsExperimentalAutocompleteEnabled;
static bool sEncodeDecodeURLHash;
static nsHtml5StringParser* sHTMLFragmentParser;
static nsIParser* sXMLFragmentParser;

View File

@ -2305,7 +2305,7 @@ nsFrameLoader::CreateStaticClone(nsIFrameLoader* aDest)
bool
nsFrameLoader::DoLoadFrameScript(const nsAString& aURL, bool aRunInGlobalScope)
{
mozilla::dom::PBrowserParent* tabParent = GetRemoteBrowser();
auto* tabParent = static_cast<TabParent*>(GetRemoteBrowser());
if (tabParent) {
return tabParent->SendLoadRemoteScript(nsString(aURL), aRunInGlobalScope);
}

View File

@ -298,28 +298,36 @@ nsLocation::GetHash(nsAString& aHash)
nsAutoString unicodeRef;
rv = uri->GetRef(ref);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsITextToSubURI> textToSubURI(
do_GetService(NS_ITEXTTOSUBURI_CONTRACTID, &rv));
if (nsContentUtils::EncodeDecodeURLHash()) {
if (NS_SUCCEEDED(rv)) {
nsAutoCString charset;
uri->GetOriginCharset(charset);
rv = textToSubURI->UnEscapeURIForUI(charset, ref, unicodeRef);
}
if (NS_FAILED(rv)) {
// Oh, well. No intl here!
NS_UnescapeURL(ref);
CopyASCIItoUTF16(ref, unicodeRef);
rv = NS_OK;
}
}
nsCOMPtr<nsITextToSubURI> textToSubURI(
do_GetService(NS_ITEXTTOSUBURI_CONTRACTID, &rv));
if (NS_SUCCEEDED(rv) && !unicodeRef.IsEmpty()) {
aHash.Assign(char16_t('#'));
aHash.Append(unicodeRef);
if (NS_SUCCEEDED(rv)) {
nsAutoCString charset;
uri->GetOriginCharset(charset);
rv = textToSubURI->UnEscapeURIForUI(charset, ref, unicodeRef);
}
if (NS_FAILED(rv)) {
// Oh, well. No intl here!
NS_UnescapeURL(ref);
CopyASCIItoUTF16(ref, unicodeRef);
rv = NS_OK;
}
}
if (NS_SUCCEEDED(rv) && !unicodeRef.IsEmpty()) {
aHash.Assign(char16_t('#'));
aHash.Append(unicodeRef);
}
} else { // URL Hash should simply return the value of the Ref segment
if (NS_SUCCEEDED(rv) && !ref.IsEmpty()) {
aHash.Assign(char16_t('#'));
AppendUTF8toUTF16(ref, aHash);
}
}
if (aHash == mCachedHash) {

View File

@ -288,7 +288,8 @@ nsXMLHttpRequest::sDontWarnAboutSyncXHR = false;
nsXMLHttpRequest::nsXMLHttpRequest()
: mResponseBodyDecodedPos(0),
mResponseType(XML_HTTP_RESPONSE_TYPE_DEFAULT),
mRequestObserver(nullptr), mState(XML_HTTP_REQUEST_UNSENT),
mRequestObserver(nullptr),
mState(XML_HTTP_REQUEST_UNSENT | XML_HTTP_REQUEST_ASYNC),
mUploadTransferred(0), mUploadTotal(0), mUploadComplete(true),
mProgressSinceLastProgressEvent(false),
mRequestSentTime(0), mTimeoutMilliseconds(0),
@ -915,10 +916,9 @@ void
nsXMLHttpRequest::SetResponseType(nsXMLHttpRequest::ResponseTypeEnum aResponseType,
ErrorResult& aRv)
{
// If the state is not OPENED or HEADERS_RECEIVED raise an
// INVALID_STATE_ERR exception and terminate these steps.
if (!(mState & (XML_HTTP_REQUEST_OPENED | XML_HTTP_REQUEST_SENT |
XML_HTTP_REQUEST_HEADERS_RECEIVED))) {
// If the state is LOADING or DONE raise an INVALID_STATE_ERR exception
// and terminate these steps.
if ((mState & (XML_HTTP_REQUEST_LOADING | XML_HTTP_REQUEST_DONE))) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}

View File

@ -323,7 +323,6 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop spec
[test_CrossSiteXHR_cache.html]
[test_CrossSiteXHR_origin.html]
skip-if = buildapp == 'b2g' || e10s # last test fails to trigger onload on e10s/b2g
[test_DOMException.html]
[test_EventSource_redirects.html]
[test_NodeIterator_basics_filters.xhtml]
[test_NodeIterator_mutations_1.xhtml]

View File

@ -1,67 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for DOMException constants</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script>
var constants = [
null,
"INDEX_SIZE_ERR",
"DOMSTRING_SIZE_ERR",
"HIERARCHY_REQUEST_ERR",
"WRONG_DOCUMENT_ERR",
"INVALID_CHARACTER_ERR",
"NO_DATA_ALLOWED_ERR",
"NO_MODIFICATION_ALLOWED_ERR",
"NOT_FOUND_ERR",
"NOT_SUPPORTED_ERR",
"INUSE_ATTRIBUTE_ERR",
"INVALID_STATE_ERR",
"SYNTAX_ERR",
"INVALID_MODIFICATION_ERR",
"NAMESPACE_ERR",
"INVALID_ACCESS_ERR",
"VALIDATION_ERR",
"TYPE_MISMATCH_ERR",
"SECURITY_ERR",
"NETWORK_ERR",
"ABORT_ERR",
"URL_MISMATCH_ERR",
"QUOTA_EXCEEDED_ERR",
"TIMEOUT_ERR",
"INVALID_NODE_TYPE_ERR",
"DATA_CLONE_ERR"
];
for (var i = 0; i < constants.length; ++i) {
var constant = constants[i];
if (constant)
is(DOMException[constant], i, constant)
}
var ex = new DOMException();
ise(ex.name, "Error",
"Not passing a name should end up with 'Error' as the name");
ise(ex.message, "",
"Not passing a message should end up with empty string as the message");
ex = new DOMException("foo");
ise(ex.name, "Error",
"Not passing a name should still end up with 'Error' as the name");
ise(ex.message, "foo", "Should be using passed-in message");
ex = new DOMException("bar", "NotSupportedError");
ise(ex.name, "NotSupportedError", "Should be using the passed-in name");
ise(ex.message, "bar", "Should still be using passed-in message");
ise(ex.code, DOMException.NOT_SUPPORTED_ERR,
"Should have the right exception code");
</script>
</pre>
</body>
</html>

View File

@ -104,6 +104,12 @@ function checkResponseXMLAccessThrows(xhr) {
try { xhr.responseXML } catch (e) { didthrow = true; }
ok(didthrow, "should have thrown when accessing responseXML");
}
function checkSetResponseType(xhr, type) {
var didthrow = false;
try { xhr.responseType = type; } catch (e) { didthrow = true; }
ise(xhr.responseType, type, "responseType should be " + type);
ok(!didthrow, "should not have thrown when setting responseType");
}
function checkSetResponseTypeThrows(xhr, type) {
var didthrow = false;
try { xhr.responseType = type; } catch (e) { didthrow = true; }
@ -115,6 +121,18 @@ function checkOpenThrows(xhr, method, url, async) {
ok(didthrow, "should have thrown when open is called");
}
// test if setting responseType before calling open() works
xhr = new XMLHttpRequest();
checkSetResponseType(xhr, "");
checkSetResponseType(xhr, "text");
checkSetResponseType(xhr, "document");
checkSetResponseType(xhr, "arraybuffer");
checkSetResponseType(xhr, "blob");
checkSetResponseType(xhr, "json");
checkSetResponseType(xhr, "moz-chunked-text");
checkSetResponseType(xhr, "moz-chunked-arraybuffer");
checkOpenThrows(xhr, "GET", "file_XHR_pass2.txt", false);
// test response (sync, responseType is not changeable)
xhr = new XMLHttpRequest();
xhr.open("GET", 'file_XHR_pass2.txt', false);

View File

@ -117,7 +117,7 @@
{ url: 'http://example.com/carrot#question%3f',
base: undefined,
error: false,
hash: '#question?'
hash: '#question%3f'
},
{ url: 'https://example.com:4443?',
base: undefined,

View File

@ -4,20 +4,329 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebGL2Context.h"
#include "GLContext.h"
#include "WebGLContextUtils.h"
using namespace mozilla;
using namespace mozilla::dom;
// Returns one of FLOAT, INT, UNSIGNED_INT.
// Fixed-points (normalized ints) are considered FLOAT.
static GLenum
ValueTypeForFormat(GLenum internalFormat)
{
switch (internalFormat) {
// Fixed-point
case LOCAL_GL_R8:
case LOCAL_GL_RG8:
case LOCAL_GL_RGB565:
case LOCAL_GL_RGB8:
case LOCAL_GL_RGBA4:
case LOCAL_GL_RGB5_A1:
case LOCAL_GL_RGBA8:
case LOCAL_GL_RGB10_A2:
case LOCAL_GL_ALPHA8:
case LOCAL_GL_LUMINANCE8:
case LOCAL_GL_LUMINANCE8_ALPHA8:
case LOCAL_GL_SRGB8:
case LOCAL_GL_SRGB8_ALPHA8:
case LOCAL_GL_R8_SNORM:
case LOCAL_GL_RG8_SNORM:
case LOCAL_GL_RGB8_SNORM:
case LOCAL_GL_RGBA8_SNORM:
// Floating-point
case LOCAL_GL_R16F:
case LOCAL_GL_RG16F:
case LOCAL_GL_RGB16F:
case LOCAL_GL_RGBA16F:
case LOCAL_GL_ALPHA16F_EXT:
case LOCAL_GL_LUMINANCE16F_EXT:
case LOCAL_GL_LUMINANCE_ALPHA16F_EXT:
case LOCAL_GL_R32F:
case LOCAL_GL_RG32F:
case LOCAL_GL_RGB32F:
case LOCAL_GL_RGBA32F:
case LOCAL_GL_ALPHA32F_EXT:
case LOCAL_GL_LUMINANCE32F_EXT:
case LOCAL_GL_LUMINANCE_ALPHA32F_EXT:
case LOCAL_GL_R11F_G11F_B10F:
case LOCAL_GL_RGB9_E5:
return LOCAL_GL_FLOAT;
// Int
case LOCAL_GL_R8I:
case LOCAL_GL_RG8I:
case LOCAL_GL_RGB8I:
case LOCAL_GL_RGBA8I:
case LOCAL_GL_R16I:
case LOCAL_GL_RG16I:
case LOCAL_GL_RGB16I:
case LOCAL_GL_RGBA16I:
case LOCAL_GL_R32I:
case LOCAL_GL_RG32I:
case LOCAL_GL_RGB32I:
case LOCAL_GL_RGBA32I:
return LOCAL_GL_INT;
// Unsigned int
case LOCAL_GL_R8UI:
case LOCAL_GL_RG8UI:
case LOCAL_GL_RGB8UI:
case LOCAL_GL_RGBA8UI:
case LOCAL_GL_R16UI:
case LOCAL_GL_RG16UI:
case LOCAL_GL_RGB16UI:
case LOCAL_GL_RGBA16UI:
case LOCAL_GL_R32UI:
case LOCAL_GL_RG32UI:
case LOCAL_GL_RGB32UI:
case LOCAL_GL_RGBA32UI:
case LOCAL_GL_RGB10_A2UI:
return LOCAL_GL_UNSIGNED_INT;
default:
MOZ_CRASH("Bad `internalFormat`.");
}
}
// -------------------------------------------------------------------------
// Framebuffer objects
static bool
GetFBInfoForBlit(const WebGLFramebuffer* fb, WebGLContext* webgl,
const char* const fbInfo, GLsizei* const out_samples,
GLenum* const out_colorFormat, GLenum* const out_depthFormat,
GLenum* const out_stencilFormat)
{
auto status = fb->PrecheckFramebufferStatus();
if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE) {
webgl->ErrorInvalidOperation("blitFramebuffer: %s is not"
" framebuffer-complete.", fbInfo);
return false;
}
*out_samples = 1; // TODO
if (fb->ColorAttachment(0).IsDefined()) {
const auto& attachement = fb->ColorAttachment(0);
*out_colorFormat = attachement.EffectiveInternalFormat().get();
} else {
*out_colorFormat = 0;
}
if (fb->DepthStencilAttachment().IsDefined()) {
const auto& attachement = fb->DepthStencilAttachment();
*out_depthFormat = attachement.EffectiveInternalFormat().get();
*out_stencilFormat = *out_depthFormat;
} else {
if (fb->DepthAttachment().IsDefined()) {
const auto& attachement = fb->DepthAttachment();
*out_depthFormat = attachement.EffectiveInternalFormat().get();
} else {
*out_depthFormat = 0;
}
if (fb->StencilAttachment().IsDefined()) {
const auto& attachement = fb->StencilAttachment();
*out_stencilFormat = attachement.EffectiveInternalFormat().get();
} else {
*out_stencilFormat = 0;
}
}
return true;
}
void
WebGL2Context::BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter)
{
MOZ_CRASH("Not Implemented.");
const GLbitfield validBits = LOCAL_GL_COLOR_BUFFER_BIT |
LOCAL_GL_DEPTH_BUFFER_BIT |
LOCAL_GL_STENCIL_BUFFER_BIT;
if ((mask | validBits) != validBits) {
ErrorInvalidValue("blitFramebuffer: Invalid bit set in mask.");
return;
}
switch (filter) {
case LOCAL_GL_NEAREST:
case LOCAL_GL_LINEAR:
break;
default:
ErrorInvalidEnumInfo("blitFramebuffer: Bad `filter`:", filter);
return;
}
const GLbitfield depthAndStencilBits = LOCAL_GL_DEPTH_BUFFER_BIT |
LOCAL_GL_STENCIL_BUFFER_BIT;
if (mask & depthAndStencilBits &&
filter != LOCAL_GL_NEAREST)
{
ErrorInvalidOperation("blitFramebuffer: DEPTH_BUFFER_BIT and"
" STENCIL_BUFFER_BIT can only be used with"
" NEAREST filtering.");
return;
}
if (mBoundReadFramebuffer == mBoundDrawFramebuffer) {
// TODO: It's actually more complicated than this. We need to check that
// the underlying buffers are not the same, not the framebuffers
// themselves.
ErrorInvalidOperation("blitFramebuffer: Source and destination must"
" differ.");
return;
}
GLsizei srcSamples;
GLenum srcColorFormat;
GLenum srcDepthFormat;
GLenum srcStencilFormat;
if (mBoundReadFramebuffer) {
if (!GetFBInfoForBlit(mBoundReadFramebuffer, this, "READ_FRAMEBUFFER",
&srcSamples, &srcColorFormat, &srcDepthFormat,
&srcStencilFormat))
{
return;
}
} else {
srcSamples = 1; // Always 1.
// TODO: Don't hardcode these.
srcColorFormat = mOptions.alpha ? LOCAL_GL_RGBA8 : LOCAL_GL_RGB8;
if (mOptions.depth && mOptions.stencil) {
srcDepthFormat = LOCAL_GL_DEPTH24_STENCIL8;
srcStencilFormat = srcDepthFormat;
} else {
if (mOptions.depth) {
srcDepthFormat = LOCAL_GL_DEPTH_COMPONENT16;
}
if (mOptions.stencil) {
srcStencilFormat = LOCAL_GL_STENCIL_INDEX8;
}
}
}
GLsizei dstSamples;
GLenum dstColorFormat;
GLenum dstDepthFormat;
GLenum dstStencilFormat;
if (mBoundDrawFramebuffer) {
if (!GetFBInfoForBlit(mBoundDrawFramebuffer, this, "DRAW_FRAMEBUFFER",
&dstSamples, &dstColorFormat, &dstDepthFormat,
&dstStencilFormat))
{
return;
}
} else {
dstSamples = gl->Screen()->Samples();
// TODO: Don't hardcode these.
dstColorFormat = mOptions.alpha ? LOCAL_GL_RGBA8 : LOCAL_GL_RGB8;
if (mOptions.depth && mOptions.stencil) {
dstDepthFormat = LOCAL_GL_DEPTH24_STENCIL8;
dstStencilFormat = dstDepthFormat;
} else {
if (mOptions.depth) {
dstDepthFormat = LOCAL_GL_DEPTH_COMPONENT16;
}
if (mOptions.stencil) {
dstStencilFormat = LOCAL_GL_STENCIL_INDEX8;
}
}
}
if (mask & LOCAL_GL_COLOR_BUFFER_BIT) {
const GLenum srcColorType = srcColorFormat ? ValueTypeForFormat(srcColorFormat)
: 0;
const GLenum dstColorType = dstColorFormat ? ValueTypeForFormat(dstColorFormat)
: 0;
if (dstColorType != srcColorType) {
ErrorInvalidOperation("blitFramebuffer: Color buffer value type"
" mismatch.");
return;
}
const bool srcIsInt = srcColorType == LOCAL_GL_INT ||
srcColorType == LOCAL_GL_UNSIGNED_INT;
if (srcIsInt && filter != LOCAL_GL_NEAREST) {
ErrorInvalidOperation("blitFramebuffer: Integer read buffers can only"
" be filtered with NEAREST.");
return;
}
}
/* GLES 3.0.4, p199:
* Calling BlitFramebuffer will result in an INVALID_OPERATION error if
* mask includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT, and the source
* and destination depth and stencil buffer formats do not match.
*
* jgilbert: The wording is such that if only DEPTH_BUFFER_BIT is specified,
* the stencil formats must match. This seems wrong. It could be a spec bug,
* or I could be missing an interaction in one of the earlier paragraphs.
*/
if (mask & LOCAL_GL_DEPTH_BUFFER_BIT &&
dstDepthFormat != srcDepthFormat)
{
ErrorInvalidOperation("blitFramebuffer: Depth buffer formats must match"
" if selected.");
return;
}
if (mask & LOCAL_GL_STENCIL_BUFFER_BIT &&
dstStencilFormat != srcStencilFormat)
{
ErrorInvalidOperation("blitFramebuffer: Stencil buffer formats must"
" match if selected.");
return;
}
if (dstSamples != 1) {
ErrorInvalidOperation("blitFramebuffer: DRAW_FRAMEBUFFER may not have"
" multiple samples.");
return;
}
if (srcSamples != 1) {
if (mask & LOCAL_GL_COLOR_BUFFER_BIT &&
dstColorFormat != srcColorFormat)
{
ErrorInvalidOperation("blitFramebuffer: Color buffer formats must"
" match if selected, when reading from a"
" multisampled source.");
return;
}
if (dstX0 != srcX0 ||
dstX1 != srcX1 ||
dstY0 != srcY0 ||
dstY1 != srcY1)
{
ErrorInvalidOperation("blitFramebuffer: If the source is"
" multisampled, then the source and dest"
" regions must match exactly.");
return;
}
}
MakeContextCurrent();
gl->fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1,
dstX0, dstY0, dstX1, dstY1,
mask, filter);
}
void
@ -57,16 +366,39 @@ WebGL2Context::InvalidateFramebuffer(GLenum target, const dom::Sequence<GLenum>&
{
if (IsContextLost())
return;
MakeContextCurrent();
if (target != LOCAL_GL_FRAMEBUFFER)
return ErrorInvalidEnumInfo("invalidateFramebuffer: target", target);
for (size_t i = 0; i < attachments.Length(); i++) {
if (!ValidateFramebufferAttachment(attachments[i], "invalidateFramebuffer"))
return;
if (!ValidateFramebufferTarget(target, "framebufferRenderbuffer"))
return;
const WebGLFramebuffer* fb;
bool isDefaultFB;
switch (target) {
case LOCAL_GL_FRAMEBUFFER:
case LOCAL_GL_DRAW_FRAMEBUFFER:
fb = mBoundDrawFramebuffer;
isDefaultFB = gl->Screen()->IsDrawFramebufferDefault();
break;
case LOCAL_GL_READ_FRAMEBUFFER:
fb = mBoundReadFramebuffer;
isDefaultFB = gl->Screen()->IsReadFramebufferDefault();
break;
default:
MOZ_CRASH("Bad target.");
}
if (!mBoundFramebuffer && !gl->IsDrawingToDefaultFramebuffer()) {
for (size_t i = 0; i < attachments.Length(); i++) {
if (!ValidateFramebufferAttachment(fb, attachments[i],
"invalidateFramebuffer"))
{
return;
}
}
if (!fb && !isDefaultFB) {
dom::Sequence<GLenum> tmpAttachments;
TranslateDefaultAttachments(attachments, &tmpAttachments);
gl->fInvalidateFramebuffer(target, tmpAttachments.Length(), tmpAttachments.Elements());
@ -81,16 +413,39 @@ WebGL2Context::InvalidateSubFramebuffer(GLenum target, const dom::Sequence<GLenu
{
if (IsContextLost())
return;
MakeContextCurrent();
if (target != LOCAL_GL_FRAMEBUFFER)
return ErrorInvalidEnumInfo("invalidateFramebuffer: target", target);
for (size_t i = 0; i < attachments.Length(); i++) {
if (!ValidateFramebufferAttachment(attachments[i], "invalidateSubFramebuffer"))
return;
if (!ValidateFramebufferTarget(target, "framebufferRenderbuffer"))
return;
const WebGLFramebuffer* fb;
bool isDefaultFB;
switch (target) {
case LOCAL_GL_FRAMEBUFFER:
case LOCAL_GL_DRAW_FRAMEBUFFER:
fb = mBoundDrawFramebuffer;
isDefaultFB = gl->Screen()->IsDrawFramebufferDefault();
break;
case LOCAL_GL_READ_FRAMEBUFFER:
fb = mBoundReadFramebuffer;
isDefaultFB = gl->Screen()->IsReadFramebufferDefault();
break;
default:
MOZ_CRASH("Bad target.");
}
if (!mBoundFramebuffer && !gl->IsDrawingToDefaultFramebuffer()) {
for (size_t i = 0; i < attachments.Length(); i++) {
if (!ValidateFramebufferAttachment(fb, attachments[i],
"invalidateSubFramebuffer"))
{
return;
}
}
if (!fb && !isDefaultFB) {
dom::Sequence<GLenum> tmpAttachments;
TranslateDefaultAttachments(attachments, &tmpAttachments);
gl->fInvalidateSubFramebuffer(target, tmpAttachments.Length(), tmpAttachments.Elements(),

View File

@ -330,7 +330,8 @@ WebGLContext::DestroyResourcesAndContext()
mBoundTransformFeedbackBuffer = nullptr;
mBoundUniformBuffer = nullptr;
mCurrentProgram = nullptr;
mBoundFramebuffer = nullptr;
mBoundDrawFramebuffer = nullptr;
mBoundReadFramebuffer = nullptr;
mActiveOcclusionQuery = nullptr;
mBoundRenderbuffer = nullptr;
mBoundVertexArray = nullptr;
@ -1887,7 +1888,8 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebGLContext,
mBoundTransformFeedbackBuffer,
mBoundUniformBuffer,
mCurrentProgram,
mBoundFramebuffer,
mBoundDrawFramebuffer,
mBoundReadFramebuffer,
mBoundRenderbuffer,
mBoundVertexArray,
mDefaultVertexArray,

View File

@ -312,7 +312,8 @@ public:
uint32_t Generation() { return mGeneration.value(); }
// Returns null if the current bound FB is not likely complete.
const WebGLRectangleObject* CurValidFBRectObject() const;
const WebGLRectangleObject* CurValidDrawFBRectObject() const;
const WebGLRectangleObject* CurValidReadFBRectObject() const;
static const size_t kMaxColorAttachments = 16;
@ -415,7 +416,8 @@ public:
GLint level);
// Framebuffer validation
bool ValidateFramebufferAttachment(GLenum attachment, const char* funcName);
bool ValidateFramebufferAttachment(const WebGLFramebuffer* fb,
GLenum attachment, const char* funcName);
void FrontFace(GLenum mode);
void GenerateMipmap(GLenum target);
@ -1404,7 +1406,10 @@ protected:
uint32_t mMaxFramebufferColorAttachments;
WebGLRefPtr<WebGLFramebuffer> mBoundFramebuffer;
bool ValidateFramebufferTarget(GLenum target, const char* const info);
WebGLRefPtr<WebGLFramebuffer> mBoundDrawFramebuffer;
WebGLRefPtr<WebGLFramebuffer> mBoundReadFramebuffer;
WebGLRefPtr<WebGLRenderbuffer> mBoundRenderbuffer;
WebGLRefPtr<WebGLTransformFeedback> mBoundTransformFeedback;
WebGLRefPtr<WebGLVertexArray> mBoundVertexArray;

View File

@ -99,8 +99,8 @@ bool WebGLContext::DrawArrays_check(GLint first, GLsizei count, GLsizei primcoun
MakeContextCurrent();
if (mBoundFramebuffer) {
if (!mBoundFramebuffer->CheckAndInitializeAttachments()) {
if (mBoundDrawFramebuffer) {
if (!mBoundDrawFramebuffer->CheckAndInitializeAttachments()) {
ErrorInvalidFramebufferOperation("%s: incomplete framebuffer", info);
return false;
}
@ -280,8 +280,8 @@ WebGLContext::DrawElements_check(GLsizei count, GLenum type,
MakeContextCurrent();
if (mBoundFramebuffer) {
if (!mBoundFramebuffer->CheckAndInitializeAttachments()) {
if (mBoundDrawFramebuffer) {
if (!mBoundDrawFramebuffer->CheckAndInitializeAttachments()) {
ErrorInvalidFramebufferOperation("%s: incomplete framebuffer", info);
return false;
}
@ -370,7 +370,7 @@ void WebGLContext::Draw_cleanup()
UndoFakeVertexAttrib0();
UnbindFakeBlackTextures();
if (!mBoundFramebuffer) {
if (!mBoundDrawFramebuffer) {
Invalidate();
mShouldPresent = true;
MOZ_ASSERT(!mBackbufferNeedsClear);
@ -388,7 +388,7 @@ void WebGLContext::Draw_cleanup()
}
// Let's check the viewport
const WebGLRectangleObject* rect = CurValidFBRectObject();
const WebGLRectangleObject* rect = CurValidDrawFBRectObject();
if (rect) {
if (mViewportWidth > rect->Width() ||
mViewportHeight > rect->Height())

View File

@ -29,8 +29,8 @@ WebGLContext::Clear(GLbitfield mask)
GenerateWarning("Calling gl.clear() with RASTERIZER_DISCARD enabled has no effects.");
}
if (mBoundFramebuffer) {
if (!mBoundFramebuffer->CheckAndInitializeAttachments())
if (mBoundDrawFramebuffer) {
if (!mBoundDrawFramebuffer->CheckAndInitializeAttachments())
return ErrorInvalidFramebufferOperation("clear: incomplete framebuffer");
gl->fClear(mask);
@ -131,12 +131,11 @@ WebGLContext::DrawBuffers(const dom::Sequence<GLenum>& buffers)
const size_t buffersLength = buffers.Length();
if (buffersLength == 0) {
if (!buffersLength) {
return ErrorInvalidValue("drawBuffers: invalid <buffers> (buffers must not be empty)");
}
if (mBoundFramebuffer == 0)
{
if (!mBoundDrawFramebuffer) {
// OK: we are rendering in the default framebuffer
/* EXT_draw_buffers :

View File

@ -58,24 +58,37 @@ using namespace mozilla::gfx;
static bool BaseTypeAndSizeFromUniformType(GLenum uType, GLenum* baseType,
GLint* unitSize);
const WebGLRectangleObject*
WebGLContext::CurValidFBRectObject() const
static const WebGLRectangleObject*
CurValidFBRectObject(const WebGLContext* webgl,
const WebGLFramebuffer* boundFB)
{
const WebGLRectangleObject* rect = nullptr;
if (mBoundFramebuffer) {
if (boundFB) {
// We don't really need to ask the driver.
// Use 'precheck' to just check that our internal state looks good.
FBStatus precheckStatus = mBoundFramebuffer->PrecheckFramebufferStatus();
FBStatus precheckStatus = boundFB->PrecheckFramebufferStatus();
if (precheckStatus == LOCAL_GL_FRAMEBUFFER_COMPLETE)
rect = &mBoundFramebuffer->RectangleObject();
rect = &boundFB->RectangleObject();
} else {
rect = static_cast<const WebGLRectangleObject*>(this);
rect = static_cast<const WebGLRectangleObject*>(webgl);
}
return rect;
}
const WebGLRectangleObject*
WebGLContext::CurValidDrawFBRectObject() const
{
return CurValidFBRectObject(this, mBoundDrawFramebuffer);
}
const WebGLRectangleObject*
WebGLContext::CurValidReadFBRectObject() const
{
return CurValidFBRectObject(this, mBoundReadFramebuffer);
}
//
// WebGL API
//
@ -164,8 +177,8 @@ WebGLContext::BindFramebuffer(GLenum target, WebGLFramebuffer* wfb)
if (IsContextLost())
return;
if (target != LOCAL_GL_FRAMEBUFFER)
return ErrorInvalidEnum("bindFramebuffer: target must be GL_FRAMEBUFFER");
if (!ValidateFramebufferTarget(target, "bindFramebuffer"))
return;
if (!ValidateObjectAllowDeletedOrNull("bindFramebuffer", wfb))
return;
@ -184,7 +197,20 @@ WebGLContext::BindFramebuffer(GLenum target, WebGLFramebuffer* wfb)
gl->fBindFramebuffer(target, framebuffername);
}
mBoundFramebuffer = wfb;
switch (target) {
case LOCAL_GL_FRAMEBUFFER:
mBoundDrawFramebuffer = wfb;
mBoundReadFramebuffer = wfb;
break;
case LOCAL_GL_DRAW_FRAMEBUFFER:
mBoundDrawFramebuffer = wfb;
break;
case LOCAL_GL_READ_FRAMEBUFFER:
mBoundReadFramebuffer = wfb;
break;
default:
break;
}
}
void
@ -351,30 +377,38 @@ WebGLContext::CheckFramebufferStatus(GLenum target)
if (IsContextLost())
return LOCAL_GL_FRAMEBUFFER_UNSUPPORTED;
if (target != LOCAL_GL_FRAMEBUFFER) {
ErrorInvalidEnum("checkFramebufferStatus: target must be FRAMEBUFFER");
if (!ValidateFramebufferTarget(target, "invalidateFramebuffer"))
return 0;
WebGLFramebuffer* fb;
switch (target) {
case LOCAL_GL_FRAMEBUFFER:
case LOCAL_GL_DRAW_FRAMEBUFFER:
fb = mBoundDrawFramebuffer;
break;
case LOCAL_GL_READ_FRAMEBUFFER:
fb = mBoundReadFramebuffer;
break;
default:
MOZ_CRASH("Bad target.");
}
if (!mBoundFramebuffer)
if (!fb)
return LOCAL_GL_FRAMEBUFFER_COMPLETE;
return mBoundFramebuffer->CheckFramebufferStatus().get();
return fb->CheckFramebufferStatus().get();
}
void
WebGLContext::CopyTexSubImage2D_base(TexImageTarget texImageTarget,
GLint level,
WebGLContext::CopyTexSubImage2D_base(TexImageTarget texImageTarget, GLint level,
TexInternalFormat internalformat,
GLint xoffset,
GLint yoffset,
GLint x,
GLint y,
GLsizei width,
GLsizei height,
GLint xoffset, GLint yoffset, GLint x,
GLint y, GLsizei width, GLsizei height,
bool sub)
{
const WebGLRectangleObject* framebufferRect = CurValidFBRectObject();
const WebGLRectangleObject* framebufferRect = CurValidReadFBRectObject();
GLsizei framebufferWidth = framebufferRect ? framebufferRect->Width() : 0;
GLsizei framebufferHeight = framebufferRect ? framebufferRect->Height() : 0;
@ -399,7 +433,7 @@ WebGLContext::CopyTexSubImage2D_base(TexImageTarget texImageTarget,
if (!ValidateCopyTexImage(internalformat.get(), func, dims))
return;
if (!mBoundFramebuffer)
if (!mBoundReadFramebuffer)
ClearBackbufferIfNeeded();
MakeContextCurrent();
@ -416,8 +450,8 @@ WebGLContext::CopyTexSubImage2D_base(TexImageTarget texImageTarget,
}
TexType framebuffertype = LOCAL_GL_NONE;
if (mBoundFramebuffer) {
TexInternalFormat framebuffereffectiveformat = mBoundFramebuffer->ColorAttachment(0).EffectiveInternalFormat();
if (mBoundReadFramebuffer) {
TexInternalFormat framebuffereffectiveformat = mBoundReadFramebuffer->ColorAttachment(0).EffectiveInternalFormat();
framebuffertype = TypeFromInternalFormat(framebuffereffectiveformat);
} else {
// FIXME - here we're assuming that the default framebuffer is backed by UNSIGNED_BYTE
@ -541,7 +575,7 @@ WebGLContext::CopyTexImage2D(GLenum rawTexImgTarget,
if (!ValidateCopyTexImage(internalformat, func, dims))
return;
if (!mBoundFramebuffer)
if (!mBoundReadFramebuffer)
ClearBackbufferIfNeeded();
CopyTexSubImage2D_base(rawTexImgTarget, level, internalformat, 0, 0, x, y, width, height, false);
@ -605,7 +639,7 @@ WebGLContext::CopyTexSubImage2D(GLenum rawTexImgTarget,
if (yoffset + height > texHeight || yoffset + height < 0)
return ErrorInvalidValue("copyTexSubImage2D: yoffset+height is too large");
if (!mBoundFramebuffer)
if (!mBoundReadFramebuffer)
ClearBackbufferIfNeeded();
if (imageInfo.HasUninitializedImageData()) {
@ -681,9 +715,18 @@ WebGLContext::DeleteFramebuffer(WebGLFramebuffer* fbuf)
fbuf->RequestDelete();
if (mBoundFramebuffer == fbuf)
BindFramebuffer(LOCAL_GL_FRAMEBUFFER,
if (mBoundReadFramebuffer == mBoundDrawFramebuffer) {
if (mBoundDrawFramebuffer == fbuf) {
BindFramebuffer(LOCAL_GL_FRAMEBUFFER,
static_cast<WebGLFramebuffer*>(nullptr));
}
} else if (mBoundDrawFramebuffer == fbuf) {
BindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER,
static_cast<WebGLFramebuffer*>(nullptr));
} else if (mBoundReadFramebuffer == fbuf) {
BindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER,
static_cast<WebGLFramebuffer*>(nullptr));
}
}
void
@ -698,8 +741,11 @@ WebGLContext::DeleteRenderbuffer(WebGLRenderbuffer* rbuf)
if (!rbuf || rbuf->IsDeleted())
return;
if (mBoundFramebuffer)
mBoundFramebuffer->DetachRenderbuffer(rbuf);
if (mBoundDrawFramebuffer)
mBoundDrawFramebuffer->DetachRenderbuffer(rbuf);
if (mBoundReadFramebuffer)
mBoundReadFramebuffer->DetachRenderbuffer(rbuf);
// Invalidate framebuffer status cache
rbuf->NotifyFBsStatusChanged();
@ -723,8 +769,11 @@ WebGLContext::DeleteTexture(WebGLTexture* tex)
if (!tex || tex->IsDeleted())
return;
if (mBoundFramebuffer)
mBoundFramebuffer->DetachTexture(tex);
if (mBoundDrawFramebuffer)
mBoundDrawFramebuffer->DetachTexture(tex);
if (mBoundReadFramebuffer)
mBoundReadFramebuffer->DetachTexture(tex);
// Invalidate framebuffer status cache
tex->NotifyFBsStatusChanged();
@ -823,19 +872,41 @@ WebGLContext::FramebufferRenderbuffer(GLenum target, GLenum attachment,
if (IsContextLost())
return;
if (!mBoundFramebuffer)
return ErrorInvalidOperation("framebufferRenderbuffer: cannot modify framebuffer 0");
if (target != LOCAL_GL_FRAMEBUFFER)
return ErrorInvalidEnumInfo("framebufferRenderbuffer: target", target);
if (rbtarget != LOCAL_GL_RENDERBUFFER)
return ErrorInvalidEnumInfo("framebufferRenderbuffer: renderbuffer target:", rbtarget);
if (!ValidateFramebufferAttachment(attachment, "framebufferRenderbuffer"))
if (!ValidateFramebufferTarget(target, "framebufferRenderbuffer"))
return;
return mBoundFramebuffer->FramebufferRenderbuffer(attachment, rbtarget, wrb);
WebGLFramebuffer* fb;
switch (target) {
case LOCAL_GL_FRAMEBUFFER:
case LOCAL_GL_DRAW_FRAMEBUFFER:
fb = mBoundDrawFramebuffer;
break;
case LOCAL_GL_READ_FRAMEBUFFER:
fb = mBoundReadFramebuffer;
break;
default:
MOZ_CRASH("Bad target.");
}
if (!fb) {
return ErrorInvalidOperation("framebufferRenderbuffer: cannot modify"
" framebuffer 0.");
}
if (rbtarget != LOCAL_GL_RENDERBUFFER) {
return ErrorInvalidEnumInfo("framebufferRenderbuffer: rbtarget:",
rbtarget);
}
if (!ValidateFramebufferAttachment(fb, attachment,
"framebufferRenderbuffer"))
{
return;
}
fb->FramebufferRenderbuffer(attachment, rbtarget, wrb);
}
void
@ -848,23 +919,41 @@ WebGLContext::FramebufferTexture2D(GLenum target,
if (IsContextLost())
return;
if (!mBoundFramebuffer)
return ErrorInvalidOperation("framebufferRenderbuffer: cannot modify framebuffer 0");
if (!ValidateFramebufferTarget(target, "framebufferTexture2D"))
return;
if (target != LOCAL_GL_FRAMEBUFFER)
return ErrorInvalidEnumInfo("framebufferTexture2D: target", target);
WebGLFramebuffer* fb;
switch (target) {
case LOCAL_GL_FRAMEBUFFER:
case LOCAL_GL_DRAW_FRAMEBUFFER:
fb = mBoundDrawFramebuffer;
break;
case LOCAL_GL_READ_FRAMEBUFFER:
fb = mBoundReadFramebuffer;
break;
default:
MOZ_CRASH("Bad target.");
}
if (!fb) {
return ErrorInvalidOperation("framebufferTexture2D: cannot modify"
" framebuffer 0.");
}
if (textarget != LOCAL_GL_TEXTURE_2D &&
(textarget < LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
textarget > LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))
{
return ErrorInvalidEnumInfo("framebufferTexture2D: invalid texture target", textarget);
return ErrorInvalidEnumInfo("framebufferTexture2D: textarget:",
textarget);
}
if (!ValidateFramebufferAttachment(attachment, "framebufferTexture2D"))
if (!ValidateFramebufferAttachment(fb, attachment, "framebufferTexture2D"))
return;
return mBoundFramebuffer->FramebufferTexture2D(attachment, textarget, tobj, level);
fb->FramebufferTexture2D(attachment, textarget, tobj, level);
}
void
@ -1148,25 +1237,42 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx,
if (IsContextLost())
return JS::NullValue();
if (target != LOCAL_GL_FRAMEBUFFER) {
ErrorInvalidEnumInfo("getFramebufferAttachmentParameter: target", target);
if (!ValidateFramebufferTarget(target, "getFramebufferAttachmentParameter"))
return JS::NullValue();
WebGLFramebuffer* fb;
switch (target) {
case LOCAL_GL_FRAMEBUFFER:
case LOCAL_GL_DRAW_FRAMEBUFFER:
fb = mBoundDrawFramebuffer;
break;
case LOCAL_GL_READ_FRAMEBUFFER:
fb = mBoundReadFramebuffer;
break;
default:
MOZ_CRASH("Bad target.");
}
if (!fb) {
ErrorInvalidOperation("getFramebufferAttachmentParameter: cannot query"
" framebuffer 0.");
return JS::NullValue();
}
if (!mBoundFramebuffer) {
ErrorInvalidOperation("getFramebufferAttachmentParameter: cannot query framebuffer 0");
if (!ValidateFramebufferAttachment(fb, attachment,
"getFramebufferAttachmentParameter"))
{
return JS::NullValue();
}
if (!ValidateFramebufferAttachment(attachment, "getFramebufferAttachmentParameter"))
return JS::NullValue();
if (IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers))
mBoundFramebuffer->EnsureColorAttachments(attachment - LOCAL_GL_COLOR_ATTACHMENT0);
fb->EnsureColorAttachments(attachment - LOCAL_GL_COLOR_ATTACHMENT0);
MakeContextCurrent();
const WebGLFramebuffer::Attachment& fba = mBoundFramebuffer->GetAttachment(attachment);
const WebGLFramebuffer::Attachment& fba = fb->GetAttachment(attachment);
if (fba.Renderbuffer()) {
switch (pname) {
@ -2256,7 +2362,7 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
if (pixels.IsNull())
return ErrorInvalidValue("readPixels: null destination buffer");
const WebGLRectangleObject* framebufferRect = CurValidFBRectObject();
const WebGLRectangleObject* framebufferRect = CurValidReadFBRectObject();
GLsizei framebufferWidth = framebufferRect ? framebufferRect->Width() : 0;
GLsizei framebufferHeight = framebufferRect ? framebufferRect->Height() : 0;
@ -2344,11 +2450,11 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
}
bool isSourceTypeFloat = false;
if (mBoundFramebuffer &&
mBoundFramebuffer->ColorAttachmentCount() &&
mBoundFramebuffer->ColorAttachment(0).IsDefined())
if (mBoundReadFramebuffer &&
mBoundReadFramebuffer->ColorAttachmentCount() &&
mBoundReadFramebuffer->ColorAttachment(0).IsDefined())
{
isSourceTypeFloat = mBoundFramebuffer->ColorAttachment(0).IsReadableFloat();
isSourceTypeFloat = mBoundReadFramebuffer->ColorAttachment(0).IsReadableFloat();
}
if (isReadTypeFloat != isSourceTypeFloat)
@ -2357,13 +2463,13 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
// Check the format and type params to assure they are an acceptable pair (as per spec)
MakeContextCurrent();
if (mBoundFramebuffer) {
if (mBoundReadFramebuffer) {
// prevent readback of arbitrary video memory through uninitialized renderbuffers!
if (!mBoundFramebuffer->CheckAndInitializeAttachments())
if (!mBoundReadFramebuffer->CheckAndInitializeAttachments())
return ErrorInvalidFramebufferOperation("readPixels: incomplete framebuffer");
GLenum readPlaneBits = LOCAL_GL_COLOR_BUFFER_BIT;
if (!mBoundFramebuffer->HasCompletePlanes(readPlaneBits)) {
if (!mBoundReadFramebuffer->HasCompletePlanes(readPlaneBits)) {
return ErrorInvalidOperation("readPixels: Read source attachment doesn't have the"
" correct color/depth/stencil type.");
}
@ -2486,8 +2592,8 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
return;
bool needAlphaFilled;
if (mBoundFramebuffer) {
needAlphaFilled = !mBoundFramebuffer->ColorAttachment(0).HasAlpha();
if (mBoundReadFramebuffer) {
needAlphaFilled = !mBoundReadFramebuffer->ColorAttachment(0).HasAlpha();
} else {
needAlphaFilled = !mOptions.alpha;
}

View File

@ -74,15 +74,15 @@ bool
WebGLContext::GetStencilBits(GLint* out_stencilBits)
{
*out_stencilBits = 0;
if (mBoundFramebuffer) {
if (mBoundFramebuffer->HasDepthStencilConflict()) {
if (mBoundDrawFramebuffer) {
if (mBoundDrawFramebuffer->HasDepthStencilConflict()) {
// Error, we don't know which stencil buffer's bits to use
ErrorInvalidFramebufferOperation("getParameter: framebuffer has two stencil buffers bound");
return false;
}
if (mBoundFramebuffer->StencilAttachment().IsDefined() ||
mBoundFramebuffer->DepthStencilAttachment().IsDefined())
if (mBoundDrawFramebuffer->StencilAttachment().IsDefined() ||
mBoundDrawFramebuffer->DepthStencilAttachment().IsDefined())
{
*out_stencilBits = 8;
}
@ -150,7 +150,7 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
} else if (pname >= LOCAL_GL_DRAW_BUFFER0 &&
pname < GLenum(LOCAL_GL_DRAW_BUFFER0 + mGLMaxDrawBuffers))
{
if (mBoundFramebuffer) {
if (mBoundDrawFramebuffer) {
GLint iv = 0;
gl->fGetIntegerv(pname, &iv);
return JS::Int32Value(iv);
@ -190,6 +190,10 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
case LOCAL_GL_TEXTURE_BINDING_3D: {
return WebGLObjectAsJSValue(cx, mBound3DTextures[mActiveTexture].get(), rv);
}
// DRAW_FRAMEBUFFER_BINDING is the same as FRAMEBUFFER_BINDING.
case LOCAL_GL_READ_FRAMEBUFFER_BINDING:
return WebGLObjectAsJSValue(cx, mBoundReadFramebuffer.get(), rv);
}
}
@ -509,8 +513,9 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
return WebGLObjectAsJSValue(cx, mBoundRenderbuffer.get(), rv);
}
// DRAW_FRAMEBUFFER_BINDING is the same as FRAMEBUFFER_BINDING.
case LOCAL_GL_FRAMEBUFFER_BINDING: {
return WebGLObjectAsJSValue(cx, mBoundFramebuffer.get(), rv);
return WebGLObjectAsJSValue(cx, mBoundDrawFramebuffer.get(), rv);
}
case LOCAL_GL_CURRENT_PROGRAM: {

View File

@ -598,11 +598,14 @@ WebGLContext::EnumName(GLenum glenum)
XX(DEPTH_COMPONENT32);
XX(DEPTH_STENCIL);
XX(DEPTH24_STENCIL8);
XX(DRAW_FRAMEBUFFER);
XX(ETC1_RGB8_OES);
XX(FLOAT);
XX(FRAMEBUFFER);
XX(HALF_FLOAT);
XX(LUMINANCE);
XX(LUMINANCE_ALPHA);
XX(READ_FRAMEBUFFER);
XX(RGB);
XX(RGB16F);
XX(RGB32F);
@ -771,8 +774,6 @@ WebGLContext::EnumName(GLenum glenum)
XX(DEPTH_STENCIL_ATTACHMENT);
XX(UNSIGNED_NORMALIZED);
XX(DRAW_FRAMEBUFFER_BINDING);
XX(READ_FRAMEBUFFER);
XX(DRAW_FRAMEBUFFER);
XX(READ_FRAMEBUFFER_BINDING);
XX(RENDERBUFFER_SAMPLES);
XX(FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER);
@ -1028,10 +1029,21 @@ WebGLContext::AssertCachedBindings()
}
// Bound object state
GLuint bound = mBoundFramebuffer ? mBoundFramebuffer->GLName() : 0;
AssertUintParamCorrect(gl, LOCAL_GL_FRAMEBUFFER_BINDING, bound);
if (IsWebGL2()) {
GLuint bound = mBoundDrawFramebuffer ? mBoundDrawFramebuffer->GLName()
: 0;
AssertUintParamCorrect(gl, LOCAL_GL_DRAW_FRAMEBUFFER_BINDING, bound);
bound = mCurrentProgram ? mCurrentProgram->GLName() : 0;
bound = mBoundReadFramebuffer ? mBoundReadFramebuffer->GLName() : 0;
AssertUintParamCorrect(gl, LOCAL_GL_READ_FRAMEBUFFER_BINDING, bound);
} else {
MOZ_ASSERT(mBoundDrawFramebuffer == mBoundReadFramebuffer);
GLuint bound = mBoundDrawFramebuffer ? mBoundDrawFramebuffer->GLName()
: 0;
AssertUintParamCorrect(gl, LOCAL_GL_FRAMEBUFFER_BINDING, bound);
}
GLuint bound = mCurrentProgram ? mCurrentProgram->GLName() : 0;
AssertUintParamCorrect(gl, LOCAL_GL_CURRENT_PROGRAM, bound);
// Textures

View File

@ -416,10 +416,10 @@ bool WebGLContext::ValidateGLSLString(const nsAString& string, const char* info)
* be one of depth/stencil/depth_stencil/color attachment.
*/
bool
WebGLContext::ValidateFramebufferAttachment(GLenum attachment,
WebGLContext::ValidateFramebufferAttachment(const WebGLFramebuffer* fb, GLenum attachment,
const char* funcName)
{
if (!mBoundFramebuffer) {
if (!fb) {
switch (attachment) {
case LOCAL_GL_COLOR:
case LOCAL_GL_DEPTH:
@ -1328,27 +1328,26 @@ WebGLContext::ValidateCopyTexImage(GLenum format, WebGLTexImageFunc func,
// Default framebuffer format
GLenum fboFormat = mOptions.alpha ? LOCAL_GL_RGBA : LOCAL_GL_RGB;
if (mBoundFramebuffer) {
if (!mBoundFramebuffer->CheckAndInitializeAttachments()) {
if (mBoundReadFramebuffer) {
if (!mBoundReadFramebuffer->CheckAndInitializeAttachments()) {
ErrorInvalidFramebufferOperation("%s: Incomplete framebuffer.",
InfoFrom(func, dims));
return false;
}
GLenum readPlaneBits = LOCAL_GL_COLOR_BUFFER_BIT;
if (!mBoundFramebuffer->HasCompletePlanes(readPlaneBits)) {
if (!mBoundReadFramebuffer->HasCompletePlanes(readPlaneBits)) {
ErrorInvalidOperation("%s: Read source attachment doesn't have the"
" correct color/depth/stencil type.",
InfoFrom(func, dims));
return false;
}
// Get the correct format for the framebuffer, as it's not the default
// one.
// Get the correct format for the framebuffer, as it's not the default one.
const WebGLFramebuffer::Attachment& color0 =
mBoundFramebuffer->GetAttachment(LOCAL_GL_COLOR_ATTACHMENT0);
mBoundReadFramebuffer->GetAttachment(LOCAL_GL_COLOR_ATTACHMENT0);
fboFormat = mBoundFramebuffer->GetFormatForAttachment(color0);
fboFormat = mBoundReadFramebuffer->GetFormatForAttachment(color0);
}
// Make sure the format of the framebuffer is a superset of the format
@ -1949,7 +1948,8 @@ WebGLContext::InitAndValidateGL()
mBoundTransformFeedbackBuffer = nullptr;
mCurrentProgram = nullptr;
mBoundFramebuffer = nullptr;
mBoundDrawFramebuffer = nullptr;
mBoundReadFramebuffer = nullptr;
mBoundRenderbuffer = nullptr;
MakeContextCurrent();
@ -2143,4 +2143,32 @@ WebGLContext::InitAndValidateGL()
return true;
}
bool
WebGLContext::ValidateFramebufferTarget(GLenum target,
const char* const info)
{
bool isValid = true;
switch (target) {
case LOCAL_GL_FRAMEBUFFER:
break;
case LOCAL_GL_DRAW_FRAMEBUFFER:
case LOCAL_GL_READ_FRAMEBUFFER:
isValid = IsWebGL2();
break;
default:
isValid = false;
break;
}
if (MOZ_LIKELY(isValid)) {
return true;
}
ErrorInvalidEnum("%s: Invalid target: %s (0x%04x).", info, EnumName(target),
target);
return false;
}
} // namespace mozilla

View File

@ -455,7 +455,8 @@ WebGLFramebuffer::FramebufferRenderbuffer(FBAttachment attachPoint,
RBTarget rbtarget,
WebGLRenderbuffer* rb)
{
MOZ_ASSERT(mContext->mBoundFramebuffer == this);
MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this ||
mContext->mBoundReadFramebuffer == this);
if (!mContext->ValidateObjectAllowNull("framebufferRenderbuffer: renderbuffer",
rb))
@ -496,7 +497,8 @@ WebGLFramebuffer::FramebufferTexture2D(FBAttachment attachPoint,
TexImageTarget texImageTarget,
WebGLTexture* tex, GLint level)
{
MOZ_ASSERT(mContext->mBoundFramebuffer == this);
MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this ||
mContext->mBoundReadFramebuffer == this);
if (!mContext->ValidateObjectAllowNull("framebufferTexture2D: texture",
tex))
@ -564,7 +566,7 @@ WebGLFramebuffer::GetAttachmentOrNull(FBAttachment attachPoint)
break;
}
if (!mContext->ValidateFramebufferAttachment(attachPoint.get(),
if (!mContext->ValidateFramebufferAttachment(this, attachPoint.get(),
"getAttachmentOrNull"))
{
return nullptr;
@ -593,7 +595,7 @@ WebGLFramebuffer::GetAttachment(FBAttachment attachPoint) const
break;
}
if (!mContext->ValidateFramebufferAttachment(attachPoint.get(),
if (!mContext->ValidateFramebufferAttachment(this, attachPoint.get(),
"getAttachment"))
{
MOZ_ASSERT(false);
@ -766,7 +768,8 @@ WebGLFramebuffer::RectangleObject() const
FBStatus
WebGLFramebuffer::PrecheckFramebufferStatus() const
{
MOZ_ASSERT(mContext->mBoundFramebuffer == this);
MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this ||
mContext->mBoundReadFramebuffer == this);
if (!HasDefinedAttachments())
return LOCAL_GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; // No attachments
@ -809,7 +812,9 @@ WebGLFramebuffer::HasCompletePlanes(GLbitfield mask)
if (CheckFramebufferStatus() != LOCAL_GL_FRAMEBUFFER_COMPLETE)
return false;
MOZ_ASSERT(mContext->mBoundFramebuffer == this);
MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this ||
mContext->mBoundReadFramebuffer == this);
bool hasPlanes = true;
if (mask & LOCAL_GL_COLOR_BUFFER_BIT) {
hasPlanes &= ColorAttachmentCount() &&
@ -832,7 +837,8 @@ WebGLFramebuffer::HasCompletePlanes(GLbitfield mask)
bool
WebGLFramebuffer::CheckAndInitializeAttachments()
{
MOZ_ASSERT(mContext->mBoundFramebuffer == this);
MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this ||
mContext->mBoundReadFramebuffer == this);
if (CheckFramebufferStatus() != LOCAL_GL_FRAMEBUFFER_COMPLETE)
return false;

View File

@ -578,5 +578,6 @@ skip-if = buildapp == 'b2g' || e10s
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') || e10s #Bug 931116, b2g desktop specific, initial triage
support-files = file_bug871161-1.html file_bug871161-2.html
[test_bug1013316.html]
[test_hash_encoded.html]
[test_bug1081037.html]

View File

@ -0,0 +1,91 @@
<!doctype html>
<html>
<head>
<title>Test link.hash attribute</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a id="target1" href="http://www.example.com/#q=♥â¥#hello"></a>
<a id="target2" href="http://www.example.com/#q=%E2%99%A5%C3%A2%C2%A5"></a>
<a id="target3" href="http://www.example.com/#/search/%23important"></a>
<a id="target4" href='http://www.example.com/#{"a":[13, 42], "b":{"key":"value"}}'></a>
<pre id="test">
<script>
// Tests Link::GetHash
// Check that characters aren't being encoded
var target = document.getElementById("target1");
is(target.hash, '#q=♥â¥#hello', 'Unexpected link hash');
// Check that encoded characters aren't being decoded
target = document.getElementById("target2");
is(target.hash, '#q=%E2%99%A5%C3%A2%C2%A5', 'Unexpected link hash');
// A more regular use case
target = document.getElementById("target3");
is(target.hash, '#/search/%23important', 'Unexpected link hash');
// Some JSON
target = document.getElementById("target4");
is(target.hash, '#{"a":[13, 42], "b":{"key":"value"}}', 'Unexpected link hash');
</script>
<script>
// Tests URL::GetHash
var url = new URL("http://www.example.com/#q=♥â¥#hello")
is(url.hash, '#q=♥â¥#hello', 'Unexpected url hash');
url = new URL("http://www.example.com/#q=%E2%99%A5%C3%A2%C2%A5")
is(url.hash, '#q=%E2%99%A5%C3%A2%C2%A5', 'Unexpected url hash');
url = new URL("http://www.example.com/#/search/%23important")
is(url.hash, '#/search/%23important', 'Unexpected url hash');
// Test getters and setters
url = new URL("http://www.example.com/");
url.hash = "#q=♥â¥#hello%E2%99%A5%C3%A2%C2%A5#/search/%23important"
is(url.hash, '#q=♥â¥#hello%E2%99%A5%C3%A2%C2%A5#/search/%23important', 'Unexpected url hash');
// codepath in nsStandardUrl::SetRef is different if the path is non-empty
url = new URL("http://www.example.com/test/");
url.hash = "#q=♥â¥#hello%E2%99%A5%C3%A2%C2%A5#/search/%23important"
is(url.hash, '#q=♥â¥#hello%E2%99%A5%C3%A2%C2%A5#/search/%23important', 'Unexpected url hash');
url = new URL("http://www.example.com/");
url.hash = '#{"a":[13, 42], "b":{"key":"value"}}';
is(target.hash, '#{"a":[13, 42], "b":{"key":"value"}}', 'Unexpected url hash');
var parsed = JSON.parse(target.hash.substring(1));
is(parsed.b.key, 'value', 'JSON not parsed correctly');
url = new URL("http://www.example.com/test/");
url.hash = '#{"a":[13, 42], "b":{"key":"value"}}';
is(target.hash, '#{"a":[13, 42], "b":{"key":"value"}}', 'Unexpected url hash');
parsed = JSON.parse(target.hash.substring(1));
is(parsed.b.key, 'value', 'JSON not parsed correctly');
</script>
<script>
// Tests nsLocation::GetHash
window.history.pushState(1, document.title, '#q=♥â¥#hello');
is(location.hash,'#q=♥â¥#hello', 'Unexpected location hash');
window.history.pushState(1, document.title, '#q=%E2%99%A5%C3%A2%C2%A5');
is(location.hash,'#q=%E2%99%A5%C3%A2%C2%A5', 'Unexpected location hash');
window.history.pushState(1, document.title, '#/search/%23important');
is(location.hash,'#/search/%23important', 'Unexpected location hash');
window.history.pushState(1, document.title, '#{"a":[13, 42], "b":{"key":"value"}}');
is(location.hash,'#{"a":[13, 42], "b":{"key":"value"}}', 'Unexpected location hash');
</script>
</pre>
</body>
</html>

View File

@ -994,6 +994,11 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext,
return nullptr;
}
if (TabParent* parent = TabParent::GetNextTabParent()) {
parent->SetOwnerElement(aFrameElement);
return parent;
}
ProcessPriority initialPriority = GetInitialProcessPriority(aFrameElement);
bool isInContentProcess = (XRE_GetProcessType() != GeckoProcessType_Default);
TabId tabId;

View File

@ -79,6 +79,12 @@ struct ShowInfo
double defaultScale;
};
struct FrameScriptInfo
{
nsString url;
bool runInGlobalScope;
};
prio(normal upto urgent) intr protocol PBrowser
{
manager PContent or PContentBridge;
@ -117,7 +123,8 @@ parent:
Event(RemoteDOMEvent aEvent);
intr CreateWindow(uint32_t aChromeFlags,
sync CreateWindow(PBrowser aNewTab,
uint32_t aChromeFlags,
bool aCalledFromJS,
bool aPositionSpecified,
bool aSizeSpecified,
@ -125,7 +132,7 @@ parent:
nsString aName,
nsString aFeatures,
nsString aBaseURI)
returns (bool windowIsNew, PBrowser window);
returns (bool windowOpened, FrameScriptInfo[] frameScripts);
sync SyncMessage(nsString aMessage, ClonedMessageData aData,
CpowEntry[] aCpows, Principal aPrincipal)

View File

@ -1429,93 +1429,53 @@ TabChild::ProvideWindow(nsIDOMWindow* aParent, uint32_t aChromeFlags,
// isn't a request to open a modal-type window, we're going to create a new
// <iframe mozbrowser/mozapp> and return its window here.
nsCOMPtr<nsIDocShell> docshell = do_GetInterface(aParent);
if (docshell && docshell->GetIsInBrowserOrApp() &&
!(aChromeFlags & (nsIWebBrowserChrome::CHROME_MODAL |
nsIWebBrowserChrome::CHROME_OPENAS_DIALOG |
nsIWebBrowserChrome::CHROME_OPENAS_CHROME))) {
bool iframeMoz = (docshell && docshell->GetIsInBrowserOrApp() &&
!(aChromeFlags & (nsIWebBrowserChrome::CHROME_MODAL |
nsIWebBrowserChrome::CHROME_OPENAS_DIALOG |
nsIWebBrowserChrome::CHROME_OPENAS_CHROME)));
// Note that BrowserFrameProvideWindow may return NS_ERROR_ABORT if the
// open window call was canceled. It's important that we pass this error
// code back to our caller.
return BrowserFrameProvideWindow(aParent, aURI, aName, aFeatures,
aWindowIsNew, aReturn);
if (!iframeMoz) {
int32_t openLocation =
nsWindowWatcher::GetWindowOpenLocation(aParent, aChromeFlags, aCalledFromJS,
aPositionSpecified, aSizeSpecified);
// If it turns out we're opening in the current browser, just hand over the
// current browser's docshell.
if (openLocation == nsIBrowserDOMWindow::OPEN_CURRENTWINDOW) {
nsCOMPtr<nsIWebBrowser> browser = do_GetInterface(WebNavigation());
*aWindowIsNew = false;
return browser->GetContentDOMWindow(aReturn);
}
}
int32_t openLocation =
nsWindowWatcher::GetWindowOpenLocation(aParent, aChromeFlags, aCalledFromJS,
aPositionSpecified, aSizeSpecified);
// If it turns out we're opening in the current browser, just hand over the
// current browser's docshell.
if (openLocation == nsIBrowserDOMWindow::OPEN_CURRENTWINDOW) {
nsCOMPtr<nsIWebBrowser> browser = do_GetInterface(WebNavigation());
*aWindowIsNew = false;
return browser->GetContentDOMWindow(aReturn);
}
// Otherwise, we're opening a new tab or a new window. We have to contact
// TabParent in order to do either.
PBrowserChild* newChild;
nsAutoCString uriString;
if (aURI) {
aURI->GetSpec(uriString);
}
nsCOMPtr<nsIDOMDocument> domDoc;
aParent->GetDocument(getter_AddRefs(domDoc));
if (!domDoc) {
NS_ERROR("Could retrieve document from nsIBaseWindow");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDocument> doc;
doc = do_QueryInterface(domDoc);
if (!doc) {
NS_ERROR("Document from nsIBaseWindow didn't QI to nsIDocument");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIURI> baseURI = doc->GetDocBaseURI();
if (!baseURI) {
NS_ERROR("nsIDocument didn't return a base URI");
return NS_ERROR_FAILURE;
}
nsAutoCString baseURIString;
baseURI->GetSpec(baseURIString);
nsAutoString nameString;
nameString.Assign(aName);
nsAutoCString features;
// We can assume that if content is requesting to open a window from a remote
// tab, then we want to enforce that the new window is also a remote tab.
features.Assign(aFeatures);
features.Append(",remote");
if (!CallCreateWindow(aChromeFlags, aCalledFromJS, aPositionSpecified,
aSizeSpecified, NS_ConvertUTF8toUTF16(uriString),
nameString, NS_ConvertUTF8toUTF16(features),
NS_ConvertUTF8toUTF16(baseURIString),
aWindowIsNew, &newChild)) {
return NS_ERROR_NOT_AVAILABLE;
}
nsCOMPtr<nsIDOMWindow> win =
do_GetInterface(static_cast<TabChild*>(newChild)->WebNavigation());
win.forget(aReturn);
return NS_OK;
// Note that ProvideWindowCommon may return NS_ERROR_ABORT if the
// open window call was canceled. It's important that we pass this error
// code back to our caller.
return ProvideWindowCommon(aParent,
iframeMoz,
aChromeFlags,
aCalledFromJS,
aPositionSpecified,
aSizeSpecified,
aURI,
aName,
aFeatures,
aWindowIsNew,
aReturn);
}
nsresult
TabChild::BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
nsIURI* aURI,
const nsAString& aName,
const nsACString& aFeatures,
bool* aWindowIsNew,
nsIDOMWindow** aReturn)
TabChild::ProvideWindowCommon(nsIDOMWindow* aOpener,
bool aIframeMoz,
uint32_t aChromeFlags,
bool aCalledFromJS,
bool aPositionSpecified,
bool aSizeSpecified,
nsIURI* aURI,
const nsAString& aName,
const nsACString& aFeatures,
bool* aWindowIsNew,
nsIDOMWindow** aReturn)
{
*aReturn = nullptr;
@ -1539,7 +1499,7 @@ TabChild::BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
&tabId);
nsRefPtr<TabChild> newChild = new TabChild(ContentChild::GetSingleton(), tabId,
/* TabContext */ *this, /* chromeFlags */ 0);
/* TabContext */ *this, aChromeFlags);
if (NS_FAILED(newChild->Init())) {
return NS_ERROR_ABORT;
}
@ -1548,7 +1508,7 @@ TabChild::BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
unused << Manager()->SendPBrowserConstructor(
// We release this ref in DeallocPBrowserChild
nsRefPtr<TabChild>(newChild).forget().take(),
tabId, IPCTabContext(context, mScrolling), /* chromeFlags */ 0,
tabId, IPCTabContext(context, mScrolling), aChromeFlags,
cc->GetID(), cc->IsForApp(), cc->IsForBrowser());
nsAutoCString spec;
@ -1558,9 +1518,51 @@ TabChild::BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
NS_ConvertUTF8toUTF16 url(spec);
nsString name(aName);
NS_ConvertUTF8toUTF16 features(aFeatures);
newChild->SendBrowserFrameOpenWindow(this, url, name,
features, aWindowIsNew);
nsAutoCString features(aFeatures);
nsTArray<FrameScriptInfo> frameScripts;
if (aIframeMoz) {
newChild->SendBrowserFrameOpenWindow(this, url, name,
NS_ConvertUTF8toUTF16(features),
aWindowIsNew);
} else {
nsCOMPtr<nsIDOMDocument> domDoc;
aOpener->GetDocument(getter_AddRefs(domDoc));
if (!domDoc) {
NS_ERROR("Could retrieve document from nsIBaseWindow");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDocument> doc;
doc = do_QueryInterface(domDoc);
if (!doc) {
NS_ERROR("Document from nsIBaseWindow didn't QI to nsIDocument");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIURI> baseURI = doc->GetDocBaseURI();
if (!baseURI) {
NS_ERROR("nsIDocument didn't return a base URI");
return NS_ERROR_FAILURE;
}
nsAutoCString baseURIString;
baseURI->GetSpec(baseURIString);
// We can assume that if content is requesting to open a window from a remote
// tab, then we want to enforce that the new window is also a remote tab.
features.AppendLiteral(",remote");
if (!SendCreateWindow(newChild,
aChromeFlags, aCalledFromJS, aPositionSpecified,
aSizeSpecified, url,
name, NS_ConvertUTF8toUTF16(features),
NS_ConvertUTF8toUTF16(baseURIString),
aWindowIsNew,
&frameScripts)) {
return NS_ERROR_NOT_AVAILABLE;
}
}
if (!*aWindowIsNew) {
PBrowserChild::Send__delete__(newChild);
return NS_ERROR_ABORT;
@ -1583,6 +1585,13 @@ TabChild::BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
// pretty bogus; see bug 763602.
newChild->DoFakeShow(scrolling, textureFactoryIdentifier, layersId, renderFrame);
for (size_t i = 0; i < frameScripts.Length(); i++) {
FrameScriptInfo& info = frameScripts[i];
if (!newChild->RecvLoadRemoteScript(info.url(), info.runInGlobalScope())) {
MOZ_CRASH();
}
}
nsCOMPtr<nsIDOMWindow> win = do_GetInterface(newChild->WebNavigation());
win.forget(aReturn);
return NS_OK;
@ -1914,7 +1923,14 @@ TabChild::ApplyShowInfo(const ShowInfo& aInfo)
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
if (docShell) {
nsCOMPtr<nsIDocShellTreeItem> item = do_GetInterface(docShell);
item->SetName(aInfo.name());
if (IsBrowserOrApp()) {
// B2G allows window.name to be set by changing the name attribute on the
// <iframe mozbrowser> element. window.open calls cause this attribute to
// be set to the correct value. A normal <xul:browser> element has no such
// attribute. The data we get here comes from reading the attribute, so we
// shouldn't trust it for <xul:browser> elements.
item->SetName(aInfo.name());
}
docShell->SetFullscreenAllowed(aInfo.fullscreenAllowed());
if (aInfo.isPrivate()) {
bool nonBlank;

View File

@ -574,12 +574,17 @@ private:
void UpdateTapState(const WidgetTouchEvent& aEvent, nsEventStatus aStatus);
nsresult
BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
nsIURI* aURI,
const nsAString& aName,
const nsACString& aFeatures,
bool* aWindowIsNew,
nsIDOMWindow** aReturn);
ProvideWindowCommon(nsIDOMWindow* aOpener,
bool aIframeMoz,
uint32_t aChromeFlags,
bool aCalledFromJS,
bool aPositionSpecified,
bool aSizeSpecified,
nsIURI* aURI,
const nsAString& aName,
const nsACString& aFeatures,
bool* aWindowIsNew,
nsIDOMWindow** aReturn);
bool HasValidInnerSize();

View File

@ -272,6 +272,7 @@ TabParent::TabParent(nsIContentParent* aManager,
, mChromeFlags(aChromeFlags)
, mInitedByParent(false)
, mTabId(aTabId)
, mSkipLoad(false)
{
MOZ_ASSERT(aManager);
}
@ -449,18 +450,49 @@ TabParent::RecvEvent(const RemoteDOMEvent& aEvent)
return true;
}
bool
TabParent::AnswerCreateWindow(const uint32_t& aChromeFlags,
const bool& aCalledFromJS,
const bool& aPositionSpecified,
const bool& aSizeSpecified,
const nsString& aURI,
const nsString& aName,
const nsString& aFeatures,
const nsString& aBaseURI,
bool* aWindowIsNew,
PBrowserParent** aRetVal)
struct MOZ_STACK_CLASS TabParent::AutoUseNewTab MOZ_FINAL
{
public:
AutoUseNewTab(TabParent* aNewTab, bool* aWindowIsNew)
: mNewTab(aNewTab), mWindowIsNew(aWindowIsNew)
{
MOZ_ASSERT(!TabParent::sNextTabParent);
TabParent::sNextTabParent = aNewTab;
aNewTab->mSkipLoad = true;
}
~AutoUseNewTab()
{
mNewTab->mSkipLoad = false;
if (TabParent::sNextTabParent) {
MOZ_ASSERT(TabParent::sNextTabParent == mNewTab);
TabParent::sNextTabParent = nullptr;
*mWindowIsNew = false;
}
}
private:
TabParent* mNewTab;
bool* mWindowIsNew;
};
bool
TabParent::RecvCreateWindow(PBrowserParent* aNewTab,
const uint32_t& aChromeFlags,
const bool& aCalledFromJS,
const bool& aPositionSpecified,
const bool& aSizeSpecified,
const nsString& aURI,
const nsString& aName,
const nsString& aFeatures,
const nsString& aBaseURI,
bool* aWindowIsNew,
InfallibleTArray<FrameScriptInfo>* aFrameScripts)
{
// We always expect to open a new window here. If we don't, it's an error.
*aWindowIsNew = true;
if (IsBrowserOrApp()) {
return false;
}
@ -470,6 +502,8 @@ TabParent::AnswerCreateWindow(const uint32_t& aChromeFlags,
do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, false);
TabParent* newTab = static_cast<TabParent*>(aNewTab);
nsCOMPtr<nsIContent> frame(do_QueryInterface(mFrameElement));
NS_ENSURE_TRUE(frame, false);
@ -483,8 +517,6 @@ TabParent::AnswerCreateWindow(const uint32_t& aChromeFlags,
MOZ_ASSERT(openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB ||
openLocation == nsIBrowserDOMWindow::OPEN_NEWWINDOW);
*aWindowIsNew = true;
// Opening new tabs is the easy case...
if (openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB) {
NS_ENSURE_TRUE(mBrowserDOMWindow, false);
@ -497,17 +529,18 @@ TabParent::AnswerCreateWindow(const uint32_t& aChromeFlags,
params->SetReferrer(aBaseURI);
params->SetIsPrivate(isPrivate);
AutoUseNewTab aunt(newTab, aWindowIsNew);
nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner;
mBrowserDOMWindow->OpenURIInFrame(nullptr, params,
nsIBrowserDOMWindow::OPEN_NEWTAB,
openLocation,
nsIBrowserDOMWindow::OPEN_NEW,
getter_AddRefs(frameLoaderOwner));
NS_ENSURE_TRUE(frameLoaderOwner, false);
if (!frameLoaderOwner) {
*aWindowIsNew = false;
}
nsRefPtr<nsFrameLoader> frameLoader = frameLoaderOwner->GetFrameLoader();
NS_ENSURE_TRUE(frameLoader, false);
*aRetVal = frameLoader->GetRemoteBrowser();
aFrameScripts->SwapElements(newTab->mDelayedFrameScripts);
return true;
}
@ -530,6 +563,8 @@ TabParent::AnswerCreateWindow(const uint32_t& aChromeFlags,
nsCOMPtr<nsIDOMWindow> window;
AutoUseNewTab aunt(newTab, aWindowIsNew);
rv = pwwatch->OpenWindow2(parent, finalURIString.get(),
NS_ConvertUTF16toUTF8(aName).get(),
NS_ConvertUTF16toUTF8(aFeatures).get(), aCalledFromJS,
@ -545,15 +580,45 @@ TabParent::AnswerCreateWindow(const uint32_t& aChromeFlags,
nsCOMPtr<nsITabParent> newRemoteTab = newDocShell->GetOpenedRemote();
NS_ENSURE_TRUE(newRemoteTab, false);
*aRetVal = static_cast<TabParent*>(newRemoteTab.get());
MOZ_ASSERT(static_cast<TabParent*>(newRemoteTab.get()) == newTab);
aFrameScripts->SwapElements(newTab->mDelayedFrameScripts);
return true;
}
TabParent* TabParent::sNextTabParent;
/* static */ TabParent*
TabParent::GetNextTabParent()
{
TabParent* result = sNextTabParent;
sNextTabParent = nullptr;
return result;
}
bool
TabParent::SendLoadRemoteScript(const nsString& aURL,
const bool& aRunInGlobalScope)
{
if (mSkipLoad) {
mDelayedFrameScripts.AppendElement(FrameScriptInfo(aURL, aRunInGlobalScope));
return true;
}
MOZ_ASSERT(mDelayedFrameScripts.IsEmpty());
return PBrowserParent::SendLoadRemoteScript(aURL, aRunInGlobalScope);
}
void
TabParent::LoadURL(nsIURI* aURI)
{
MOZ_ASSERT(aURI);
if (mSkipLoad) {
// Don't send the message if the child wants to load its own URL.
return;
}
if (mIsDestroyed) {
return;
}

View File

@ -134,16 +134,17 @@ public:
const nsString& aName,
const nsString& aFeatures,
bool* aOutWindowOpened) MOZ_OVERRIDE;
virtual bool AnswerCreateWindow(const uint32_t& aChromeFlags,
const bool& aCalledFromJS,
const bool& aPositionSpecified,
const bool& aSizeSpecified,
const nsString& aURI,
const nsString& aName,
const nsString& aFeatures,
const nsString& aBaseURI,
bool* aWindowIsNew,
PBrowserParent** aRetVal) MOZ_OVERRIDE;
virtual bool RecvCreateWindow(PBrowserParent* aOpener,
const uint32_t& aChromeFlags,
const bool& aCalledFromJS,
const bool& aPositionSpecified,
const bool& aSizeSpecified,
const nsString& aURI,
const nsString& aName,
const nsString& aFeatures,
const nsString& aBaseURI,
bool* aWindowIsNew,
InfallibleTArray<FrameScriptInfo>* aFrameScripts) MOZ_OVERRIDE;
virtual bool RecvSyncMessage(const nsString& aMessage,
const ClonedMessageData& aData,
const InfallibleTArray<CpowEntry>& aCpows,
@ -352,6 +353,11 @@ public:
void SetInitedByParent() { mInitedByParent = true; }
bool IsInitedByParent() const { return mInitedByParent; }
static TabParent* GetNextTabParent();
bool SendLoadRemoteScript(const nsString& aURL,
const bool& aRunInGlobalScope);
protected:
bool ReceiveMessage(const nsString& aMessage,
bool aSync,
@ -468,6 +474,35 @@ private:
TabId mTabId;
// Helper class for RecvCreateWindow.
struct AutoUseNewTab;
// When loading a new tab or window via window.open, the child process sends
// a new PBrowser to use. We store that tab in sNextTabParent and then
// proceed through the browser's normal paths to create a new
// window/tab. When it comes time to create a new TabParent, we instead use
// sNextTabParent.
static TabParent* sNextTabParent;
// When loading a new tab or window via window.open, the child is
// responsible for loading the URL it wants into the new
// TabChild. Simultaneously, though, the parent sends a LoadURL message to
// every new PBrowser (usually for about:blank). This message usually
// arrives after the child has started to load the URL it wants, and
// overrides it. To prevent this, we set mSkipLoad to true when creating the
// new tab. This flag prevents the unwanted LoadURL message from being sent
// by the parent.
bool mSkipLoad;
// When loading a new tab or window via window.open, we want to ensure that
// frame scripts for that tab are loaded before any scripts start to run in
// the window. We can't load the frame scripts the normal way, using
// separate IPC messages, since they won't be processed by the child until
// returning to the event loop, which is too late. Instead, we queue up
// frame scripts that we intend to load and send them as part of the
// CreateWindow response. Then TabChild loads them immediately.
nsTArray<FrameScriptInfo> mDelayedFrameScripts;
private:
// This is used when APZ needs to find the TabParent associated with a layer
// to dispatch events.

View File

@ -1189,7 +1189,13 @@ void MediaDecoderStateMachine::SetSyncPointForMediaStream()
}
mSyncPointInMediaStream = stream->GetLastOutputTime();
mSyncPointInDecodedStream = mStartTime + mPlayDuration;
TimeDuration timeSincePlayStart = mPlayStartTime.IsNull() ? TimeDuration(0) :
TimeStamp::Now() - mPlayStartTime;
mSyncPointInDecodedStream = mStartTime + mPlayDuration +
timeSincePlayStart.ToMicroseconds();
DECODER_LOG("SetSyncPointForMediaStream MediaStream=%lldus, DecodedStream=%lldus",
mSyncPointInMediaStream, mSyncPointInDecodedStream);
}
void MediaDecoderStateMachine::ResyncMediaStreamClock()
@ -1353,6 +1359,13 @@ void MediaDecoderStateMachine::SetAudioCaptured(bool aCaptured)
// If mStopAudioThread is true then we're already stopping the audio sink
// and since we set mAudioCaptured to true, nothing can start it again.
ScheduleStateMachine();
if (HasAudio()) {
// The audio clock is active so force a resync now in case the audio
// clock is ahead of us (observed on Android), since after mAudioCaptured
// gets set can't call GetAudioClock().
ResyncAudioClock();
}
}
mAudioCaptured = aCaptured;
}
@ -1442,6 +1455,15 @@ void MediaDecoderStateMachine::SetDormant(bool aDormant)
DECODER_LOG("SetDormant=%d", aDormant);
if (aDormant) {
if (mState == DECODER_STATE_SEEKING && !mQueuedSeekTarget.IsValid()) {
if (mSeekTarget.IsValid()) {
mQueuedSeekTarget = mSeekTarget;
} else if (mCurrentSeekTarget.IsValid()) {
mQueuedSeekTarget = mCurrentSeekTarget;
}
}
mSeekTarget.Reset();
mCurrentSeekTarget.Reset();
ScheduleStateMachine();
SetState(DECODER_STATE_DORMANT);
mDecoder->GetReentrantMonitor().NotifyAll();
@ -2916,16 +2938,15 @@ int64_t MediaDecoderStateMachine::GetClock() const
int64_t clock_time = -1;
if (!IsPlaying()) {
clock_time = mPlayDuration + mStartTime;
} else if (mDecoder->GetDecodedStream()) {
clock_time = GetCurrentTimeViaMediaStreamSync();
} else {
if (HasAudio() && !mAudioCompleted && !mAudioCaptured) {
if (mDecoder->GetDecodedStream()) {
clock_time = GetCurrentTimeViaMediaStreamSync();
} else if (HasAudio() && !mAudioCompleted && !mAudioCaptured) {
clock_time = GetAudioClock();
} else {
// Audio is disabled on this system. Sync to the system clock.
clock_time = GetVideoStreamPosition();
}
// FIXME: This assertion should also apply the case of decoding to a stream.
// Ensure the clock can never go backwards.
NS_ASSERTION(GetMediaTime() <= clock_time || mPlaybackRate <= 0,
"Clock should go forwards if the playback rate is > 0.");
@ -2951,6 +2972,14 @@ void MediaDecoderStateMachine::AdvanceFrame()
return;
}
DecodedStreamData* stream = mDecoder->GetDecodedStream();
if (stream && !stream->mStreamInitialized) {
// Output streams exist but are not initialized yet.
// Send the data we already have to allow stream clock to progress and
// avoid stalling playback.
SendStreamData();
}
const int64_t clock_time = GetClock();
TimeStamp nowTime = TimeStamp::Now();
// Skip frames up to the frame at the playback position, and figure out

View File

@ -7,6 +7,7 @@
#include "MP4Reader.h"
#include "MP4Stream.h"
#include "MediaResource.h"
#include "nsPrintfCString.h"
#include "nsSize.h"
#include "VideoUtils.h"
#include "mozilla/dom/HTMLMediaElement.h"
@ -88,32 +89,18 @@ InvokeAndRetry(ThisType* aThisVal, ReturnType(ThisType::*aMethod)(), MP4Stream*
return result;
}
MP4Stream::ReadRecord failure(-1, 0);
if (!stream->LastReadFailed(&failure) || failure == prevFailure) {
if (NS_WARN_IF(!stream->LastReadFailed(&failure))) {
return result;
}
prevFailure = failure;
// Our goal here is to forcibly read the data we want into the cache: since
// the stream is pinned, the data is guaranteed to stay in the cache once
// it's there, which means that retrying the non-blocking read from inside
// the demuxer should succeed.
//
// But there's one wrinkle: if we read less than an entire cache line and
// the data ends up in MediaCacheStream's mPartialBlockBuffer, the data can
// be returned by a blocking read but never actually committed to the cache,
// and abandoned by a subsequent seek (possibly by another stream accessing
// the same underlying resource).
//
// The way to work around this problem is to round our "priming" read up to the
// size of an entire cache block. Note that this may hit EOS for bytes that the
// original demuxer read never actually requested. This is OK though because the
// call to BlockingReadAt will still return true (just with a less-than-expected
// number of actually read bytes, which we ignore).
size_t bufferSize = failure.mCount + (MediaCacheStream::BLOCK_SIZE - failure.mCount % MediaCacheStream::BLOCK_SIZE);
nsAutoArrayPtr<uint8_t> dummyBuffer(new uint8_t[bufferSize]);
MonitorAutoUnlock unlock(*aMonitor);
size_t ignored;
if (NS_WARN_IF(!stream->BlockingReadAt(failure.mOffset, dummyBuffer, bufferSize, &ignored))) {
if (NS_WARN_IF(failure == prevFailure)) {
NS_WARNING(nsPrintfCString("Failed reading the same block twice: offset=%lld, count=%lu",
failure.mOffset, failure.mCount).get());
return result;
}
prevFailure = failure;
if (NS_WARN_IF(!stream->BlockingReadIntoCache(failure.mOffset, failure.mCount, aMonitor))) {
return result;
}
}

View File

@ -11,6 +11,7 @@ namespace mozilla {
MP4Stream::MP4Stream(MediaResource* aResource)
: mResource(aResource)
, mPinCount(0)
{
MOZ_COUNT_CTOR(MP4Stream);
MOZ_ASSERT(aResource);
@ -19,25 +20,33 @@ MP4Stream::MP4Stream(MediaResource* aResource)
MP4Stream::~MP4Stream()
{
MOZ_COUNT_DTOR(MP4Stream);
MOZ_ASSERT(mPinCount == 0);
}
bool
MP4Stream::BlockingReadAt(int64_t aOffset, void* aBuffer, size_t aCount,
size_t* aBytesRead)
MP4Stream::BlockingReadIntoCache(int64_t aOffset, size_t aCount, Monitor* aToUnlock)
{
MOZ_ASSERT(mPinCount > 0);
CacheBlock block(aOffset, aCount);
uint32_t sum = 0;
uint32_t bytesRead = 0;
do {
uint64_t offset = aOffset + sum;
char* buffer = reinterpret_cast<char*>(aBuffer) + sum;
char* buffer = reinterpret_cast<char*>(block.mBuffer.get()) + sum;
uint32_t toRead = aCount - sum;
MonitorAutoUnlock unlock(*aToUnlock);
nsresult rv = mResource->ReadAt(offset, buffer, toRead, &bytesRead);
if (NS_FAILED(rv)) {
return false;
}
sum += bytesRead;
} while (sum < aCount && bytesRead > 0);
*aBytesRead = sum;
MOZ_ASSERT(block.mCount >= sum);
block.mCount = sum;
mCache.AppendElement(block);
return true;
}
@ -64,6 +73,14 @@ bool
MP4Stream::CachedReadAt(int64_t aOffset, void* aBuffer, size_t aCount,
size_t* aBytesRead)
{
// First, check our local cache.
for (size_t i = 0; i < mCache.Length(); ++i) {
if (mCache[i].mOffset == aOffset && mCache[i].mCount >= aCount) {
memcpy(aBuffer, mCache[i].mBuffer, aCount);
*aBytesRead = aCount;
return true;
}
}
nsresult rv = mResource->ReadFromCache(reinterpret_cast<char*>(aBuffer),
aOffset, aCount);

View File

@ -12,6 +12,7 @@
#include "MediaResource.h"
#include "mozilla/Maybe.h"
#include "mozilla/Monitor.h"
namespace mozilla {
@ -21,7 +22,7 @@ class MP4Stream : public mp4_demuxer::Stream {
public:
explicit MP4Stream(MediaResource* aResource);
virtual ~MP4Stream();
bool BlockingReadAt(int64_t aOffset, void* aBuffer, size_t aCount, size_t* aBytesRead);
bool BlockingReadIntoCache(int64_t aOffset, size_t aCount, Monitor* aToUnlock);
virtual bool ReadAt(int64_t aOffset, void* aBuffer, size_t aCount,
size_t* aBytesRead) MOZ_OVERRIDE;
virtual bool CachedReadAt(int64_t aOffset, void* aBuffer, size_t aCount,
@ -44,12 +45,35 @@ public:
return false;
}
void Pin() { mResource->Pin(); }
void Unpin() { mResource->Unpin(); }
void Pin()
{
mResource->Pin();
++mPinCount;
}
void Unpin()
{
mResource->Unpin();
MOZ_ASSERT(mPinCount);
--mPinCount;
if (mPinCount == 0) {
mCache.Clear();
}
}
private:
nsRefPtr<MediaResource> mResource;
Maybe<ReadRecord> mFailedRead;
uint32_t mPinCount;
struct CacheBlock {
CacheBlock(int64_t aOffset, size_t aCount)
: mOffset(aOffset), mCount(aCount), mBuffer(new uint8_t[aCount]) {}
int64_t mOffset;
size_t mCount;
nsAutoArrayPtr<uint8_t> mBuffer;
};
nsTArray<CacheBlock> mCache;
};
}

View File

@ -338,6 +338,7 @@ skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
[test_bug919265.html]
[test_bug957847.html]
[test_bug1018933.html]
[test_bug1113600.html]
[test_can_play_type.html]
[test_can_play_type_mpeg.html]
skip-if = buildapp == 'b2g' || (toolkit == 'android' && processor == 'x86') # bug 1021675 #x86 only bug 914439

View File

@ -0,0 +1,48 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test that a video element captured to a stream mid-playback can be played to the end</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript" src="manifest.js"></script>
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
var manager = new MediaTestManager;
function startTest(test, token) {
var v = document.createElement('video');
v.style = "background-color:#aca;";
v.width = 160;
v.height = 120;
manager.started(token);
v.src = test.name;
v.ontimeupdate = function() {
if (v.currentTime < test.duration / 4) {
// Allow some time to pass before starting the capture.
return;
}
v.ontimeupdate = null;
v.mozCaptureStreamUntilEnded();
info(test.name + " capture started at " + v.currentTime + ". Duration=" + test.duration);
};
v.onended = function() {
ok(true, test.name + " ended");
removeNodeAndSource(v);
manager.finished(token);
};
document.body.appendChild(v);
v.play();
}
manager.runTests(gSmallTests, startTest);
</script>
</pre>
</body>
</html>

View File

@ -377,6 +377,7 @@ PluginModuleChromeParent::LoadModule(const char* aFilePath, uint32_t aPluginId,
parent->mShutdown = true;
return nullptr;
}
parent->mIsFlashPlugin = aPluginTag->mIsFlashPlugin;
if (!parent->mIsStartingAsync) {
int32_t launchTimeoutSecs = Preferences::GetInt(kLaunchTimeoutPref, 0);
if (!parent->mSubprocess->WaitUntilConnected(launchTimeoutSecs * 1000)) {
@ -386,7 +387,6 @@ PluginModuleChromeParent::LoadModule(const char* aFilePath, uint32_t aPluginId,
}
TimeStamp launchEnd = TimeStamp::Now();
parent->mTimeBlocked = (launchEnd - launchStart);
parent->mIsFlashPlugin = aPluginTag->mIsFlashPlugin;
return parent.forget();
}

View File

@ -418,6 +418,7 @@ Promise::JSCallback(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
}
}
args.rval().setUndefined();
return true;
}
@ -434,6 +435,7 @@ Promise::ThenableResolverCommon(JSContext* aCx, uint32_t aTask,
JS::Rooted<JSObject*> thisFunc(aCx, &args.callee());
if (!MarkAsCalledIfNotCalledBefore(aCx, thisFunc)) {
// A function from this pair has been called before.
args.rval().setUndefined();
return true;
}
@ -445,6 +447,8 @@ Promise::ThenableResolverCommon(JSContext* aCx, uint32_t aTask,
} else {
promise->RejectInternal(aCx, args.get(0));
}
args.rval().setUndefined();
return true;
}

View File

@ -1,7 +1,8 @@
[DEFAULT]
[test_abortable_promise.html]
[test_bug883683.html]
[test_promise.html]
[test_promise_utils.html]
[test_resolve.html]
[test_abortable_promise.html]
[test_resolver_return_value.html]

View File

@ -0,0 +1,40 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1120235
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1120235</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
/** Test for Bug 1120235 **/
var res, rej;
var p = new Promise(function(resolve, reject) { res = resolve; rej = reject; });
ise(res(1), undefined, "Resolve function should return undefined");
ise(rej(2), undefined, "Reject function should return undefined");
var thenable = {
then: function(resolve, reject) {
ise(resolve(3), undefined, "Thenable resolve argument should return undefined");
ise(reject(4), undefined, "Thenable reject argument should return undefined");
SimpleTest.finish();
}
};
SimpleTest.waitForExplicitFinish();
p = Promise.resolve(thenable);
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1120235">Mozilla Bug 1120235</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</html>

View File

@ -29,7 +29,7 @@ var expected = [
{ name: "", message: "uncaught exception: [object Object]" },
{ name: "", message: "foo", filename: "baz", lineNumber: 123 },
{ name: "", message: "uncaught exception: [object Object]" },
{ name: "InvalidStateError", message: "An attempt was made to use an object that is not, or is no longer, usable", filename: location, lineNumber: 60 },
{ name: "InvalidStateError", message: "An attempt was made to use an object that is not, or is no longer, usable", filename: location, lineNumber: 62 },
{ name: "ReferenceError", message: "xxx is not defined", filename: location, lineNumber: 64 },
{ name: "ReferenceError", message: "xxx is not defined", filename: location, lineNumber: 66 }
];
@ -57,9 +57,9 @@ window.onmessage = function(e) {
throw {name:3,message:4,lineNumber:123};
} else if (e.data == 7) {
var x = new XMLHttpRequest();
x.responseType = "arraybuffer";
x.open("GET", location, false);
var a = x.send();
x.responseType = "arraybuffer";
} else if (e.data == 8) {
throw new ReferenceError("xxx is not defined");
} else if (e.data == 9) {

View File

@ -111,7 +111,7 @@ onmessage = function() {
{ url: 'http://example.com/carrot#question%3f',
base: undefined,
error: false,
hash: '#question?'
hash: '#question%3f'
},
{ url: 'https://example.com:4443?',
base: undefined,

View File

@ -7398,7 +7398,8 @@ nsHTMLEditRules::JoinNodesSmart(nsIContent& aNodeLeft, nsIContent& aNodeRight)
{
// Caller responsible for left and right node being the same type
nsCOMPtr<nsINode> parent = aNodeLeft.GetParentNode();
int32_t parOffset = parent ? parent->IndexOf(&aNodeLeft) : -1;
NS_ENSURE_TRUE(parent, ::DOMPoint());
int32_t parOffset = parent->IndexOf(&aNodeLeft);
nsCOMPtr<nsINode> rightParent = aNodeRight.GetParentNode();
// If they don't have the same parent, first move the right node to after the

View File

@ -155,7 +155,7 @@ public:
ChromeTooltipListener(nsWebBrowser* inBrowser, nsIWebBrowserChrome* inChrome);
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) MOZ_OVERRIDE;
NS_IMETHOD MouseMove(nsIDOMEvent* aMouseEvent);
// Add/remove the relevant listeners, based on what interfaces
@ -227,7 +227,7 @@ public:
ChromeContextMenuListener(nsWebBrowser* inBrowser, nsIWebBrowserChrome* inChrome);
// nsIDOMContextMenuListener
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) MOZ_OVERRIDE;
// Add/remove the relevant listeners, based on what interfaces
// the embedding chrome implements.

View File

@ -94,12 +94,12 @@ public:
NS_DECL_CYCLE_COLLECTION_CLASS(nsFindContentIterator)
// nsIContentIterator
virtual nsresult Init(nsINode* aRoot)
virtual nsresult Init(nsINode* aRoot) MOZ_OVERRIDE
{
NS_NOTREACHED("internal error");
return NS_ERROR_NOT_IMPLEMENTED;
}
virtual nsresult Init(nsIDOMRange* aRange)
virtual nsresult Init(nsIDOMRange* aRange) MOZ_OVERRIDE
{
NS_NOTREACHED("internal error");
return NS_ERROR_NOT_IMPLEMENTED;
@ -107,13 +107,13 @@ public:
// Not a range because one of the endpoints may be anonymous.
nsresult Init(nsIDOMNode* aStartNode, int32_t aStartOffset,
nsIDOMNode* aEndNode, int32_t aEndOffset);
virtual void First();
virtual void Last();
virtual void Next();
virtual void Prev();
virtual nsINode* GetCurrentNode();
virtual bool IsDone();
virtual nsresult PositionAt(nsINode* aCurNode);
virtual void First() MOZ_OVERRIDE;
virtual void Last() MOZ_OVERRIDE;
virtual void Next() MOZ_OVERRIDE;
virtual void Prev() MOZ_OVERRIDE;
virtual nsINode* GetCurrentNode() MOZ_OVERRIDE;
virtual bool IsDone() MOZ_OVERRIDE;
virtual nsresult PositionAt(nsINode* aCurNode) MOZ_OVERRIDE;
protected:
virtual ~nsFindContentIterator()

View File

@ -25,7 +25,7 @@ class PrintProgressDialogChild MOZ_FINAL : public PPrintProgressDialogChild,
public:
MOZ_IMPLICIT PrintProgressDialogChild(nsIObserver* aOpenObserver);
virtual bool RecvDialogOpened();
virtual bool RecvDialogOpened() MOZ_OVERRIDE;
private:
virtual ~PrintProgressDialogChild();
@ -37,4 +37,4 @@ private:
} // namespace embedding
} // namespace mozilla
#endif
#endif

View File

@ -29,26 +29,26 @@ public:
virtual bool
RecvStateChange(
const long& stateFlags,
const nsresult& status);
const nsresult& status) MOZ_OVERRIDE;
virtual bool
RecvProgressChange(
const long& curSelfProgress,
const long& maxSelfProgress,
const long& curTotalProgress,
const long& maxTotalProgress);
const long& maxTotalProgress) MOZ_OVERRIDE;
virtual bool
RecvDocTitleChange(const nsString& newTitle);
RecvDocTitleChange(const nsString& newTitle) MOZ_OVERRIDE;
virtual bool
RecvDocURLChange(const nsString& newURL);
RecvDocURLChange(const nsString& newURL) MOZ_OVERRIDE;
virtual void
ActorDestroy(ActorDestroyReason aWhy);
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
virtual bool
Recv__delete__();
Recv__delete__() MOZ_OVERRIDE;
private:
virtual ~PrintProgressDialogParent();

View File

@ -23,10 +23,10 @@ public:
NS_DECL_NSIPRINTINGPROMPTSERVICE
virtual PPrintProgressDialogChild*
AllocPPrintProgressDialogChild();
AllocPPrintProgressDialogChild() MOZ_OVERRIDE;
virtual bool
DeallocPPrintProgressDialogChild(PPrintProgressDialogChild* aActor);
DeallocPPrintProgressDialogChild(PPrintProgressDialogChild* aActor) MOZ_OVERRIDE;
};
#endif

View File

@ -221,7 +221,7 @@ public:
nsEncoderNodeFixup();
NS_DECL_ISUPPORTS
NS_IMETHOD FixupNode(nsIDOMNode *aNode, bool *aSerializeCloneKids, nsIDOMNode **aOutNode);
NS_IMETHOD FixupNode(nsIDOMNode *aNode, bool *aSerializeCloneKids, nsIDOMNode **aOutNode) MOZ_OVERRIDE;
nsWebBrowserPersist *mWebBrowserPersist;

View File

@ -143,8 +143,8 @@ class nsWatcherWindowEnumerator : public nsISimpleEnumerator {
public:
explicit nsWatcherWindowEnumerator(nsWindowWatcher *inWatcher);
NS_IMETHOD HasMoreElements(bool *retval);
NS_IMETHOD GetNext(nsISupports **retval);
NS_IMETHOD HasMoreElements(bool *retval) MOZ_OVERRIDE;
NS_IMETHOD GetNext(nsISupports **retval) MOZ_OVERRIDE;
NS_DECL_ISUPPORTS

View File

@ -193,7 +193,7 @@ public:
// nsIObserver implementation.
NS_IMETHODIMP
Observe(nsISupports *aSubject, const char *aTopic, const char16_t *data)
Observe(nsISupports *aSubject, const char *aTopic, const char16_t *data) MOZ_OVERRIDE
{
MOZ_ASSERT(!nsCRT::strcmp(aTopic, "webapps-clear-data"));

View File

@ -29,12 +29,12 @@ class nsXPCOMDetector :
NS_DECL_ISUPPORTS
public:
nsXPCOMDetector();
NS_IMETHOD Init(nsICharsetDetectionObserver* aObserver);
NS_IMETHOD DoIt(const char* aBuf, uint32_t aLen, bool *oDontFeedMe);
NS_IMETHOD Done();
NS_IMETHOD Init(nsICharsetDetectionObserver* aObserver) MOZ_OVERRIDE;
NS_IMETHOD DoIt(const char* aBuf, uint32_t aLen, bool *oDontFeedMe) MOZ_OVERRIDE;
NS_IMETHOD Done() MOZ_OVERRIDE;
protected:
virtual ~nsXPCOMDetector();
virtual void Report(const char* aCharset);
virtual void Report(const char* aCharset) MOZ_OVERRIDE;
private:
nsCOMPtr<nsICharsetDetectionObserver> mObserver;
};
@ -49,10 +49,10 @@ class nsXPCOMStringDetector :
public:
nsXPCOMStringDetector();
NS_IMETHOD DoIt(const char* aBuf, uint32_t aLen,
const char** oCharset, nsDetectionConfident &oConf);
const char** oCharset, nsDetectionConfident &oConf) MOZ_OVERRIDE;
protected:
virtual ~nsXPCOMStringDetector();
virtual void Report(const char* aCharset);
virtual void Report(const char* aCharset) MOZ_OVERRIDE;
private:
nsCOMPtr<nsICharsetDetectionObserver> mObserver;
const char* mResult;

View File

@ -620,7 +620,11 @@ DrawBuffer::Create(GLContext* const gl,
gl->fGenFramebuffers(1, &fb);
gl->AttachBuffersToFB(0, colorMSRB, depthRB, stencilRB, fb);
UniquePtr<DrawBuffer> ret( new DrawBuffer(gl, size, fb, colorMSRB,
GLsizei samples = formats.samples;
if (!samples)
samples = 1;
UniquePtr<DrawBuffer> ret( new DrawBuffer(gl, size, samples, fb, colorMSRB,
depthRB, stencilRB) );
GLenum err = localError.GetError();

View File

@ -46,6 +46,7 @@ protected:
GLContext* const mGL;
public:
const gfx::IntSize mSize;
const GLsizei mSamples;
const GLuint mFB;
protected:
const GLuint mColorMSRB;
@ -54,12 +55,14 @@ protected:
DrawBuffer(GLContext* gl,
const gfx::IntSize& size,
GLsizei samples,
GLuint fb,
GLuint colorMSRB,
GLuint depthRB,
GLuint stencilRB)
: mGL(gl)
, mSize(size)
, mSamples(samples)
, mFB(fb)
, mColorMSRB(colorMSRB)
, mDepthRB(depthRB)
@ -198,6 +201,13 @@ public:
return mRead->mFB;
}
GLsizei Samples() const {
if (!mDraw)
return 1;
return mDraw->mSamples;
}
void DeletingFB(GLuint fb);
const gfx::IntSize& Size() const {

View File

@ -57,12 +57,6 @@ protected:
return static_cast<BasicLayerManager*>(mManager);
}
// only paints the image if aContext is non-null
void
GetAndPaintCurrentImage(DrawTarget* aTarget,
float aOpacity,
SourceSurface* aMaskSurface);
gfx::IntSize mSize;
};
@ -97,46 +91,6 @@ BasicImageLayer::Paint(DrawTarget* aDT,
GetContainer()->NotifyPaintedImage(image);
}
void
BasicImageLayer::GetAndPaintCurrentImage(DrawTarget* aTarget,
float aOpacity,
SourceSurface* aMaskSurface)
{
if (!mContainer) {
return;
}
nsRefPtr<ImageFactory> originalIF = mContainer->GetImageFactory();
mContainer->SetImageFactory(mManager->IsCompositingCheap() ?
nullptr :
BasicManager()->GetImageFactory());
IntSize size;
Image* image = nullptr;
RefPtr<SourceSurface> surf =
mContainer->LockCurrentAsSourceSurface(&size, &image);
if (!surf) {
mContainer->SetImageFactory(originalIF);
return;
}
if (aTarget) {
// The visible region can extend outside the image, so just draw
// within the image bounds.
SurfacePattern pat(surf, ExtendMode::CLAMP, Matrix(), ToFilter(mFilter));
CompositionOp op = GetEffectiveOperator(this);
DrawOptions opts(aOpacity, op);
aTarget->MaskSurface(pat, aMaskSurface, Point(0, 0), opts);
GetContainer()->NotifyPaintedImage(image);
}
mContainer->SetImageFactory(originalIF);
mContainer->UnlockCurrentImage();
}
TemporaryRef<SourceSurface>
BasicImageLayer::GetAsSourceSurface()
{

View File

@ -421,9 +421,20 @@ ContentClientRemoteBuffer::Dump(std::stringstream& aStream,
bool aDumpHtml)
{
// TODO We should combine the OnWhite/OnBlack here an just output a single image.
aStream << "\n" << aPrefix << "Surface: ";
CompositableClient::DumpTextureClient(aStream, mTextureClient);
}
void
ContentClientDoubleBuffered::Dump(std::stringstream& aStream,
const char* aPrefix,
bool aDumpHtml)
{
// TODO We should combine the OnWhite/OnBlack here an just output a single image.
aStream << "\n" << aPrefix << "Surface: ";
CompositableClient::DumpTextureClient(aStream, mFrontClient);
}
void
ContentClientDoubleBuffered::DestroyFrontBuffer()
{

View File

@ -347,6 +347,9 @@ public:
return TextureInfo(CompositableType::CONTENT_DOUBLE, mTextureFlags);
}
virtual void Dump(std::stringstream& aStream,
const char* aPrefix="",
bool aDumpHtml=false) MOZ_OVERRIDE;
protected:
virtual void DestroyFrontBuffer() MOZ_OVERRIDE;

View File

@ -507,6 +507,7 @@ void TextureClient::ForceRemove()
{
if (mValid && mActor) {
if (GetFlags() & TextureFlags::DEALLOCATE_CLIENT) {
MOZ_PERFORMANCE_WARNING("gfx", "TextureClient/Host pair requires synchronous deallocation");
if (mActor->IPCOpen()) {
mActor->SendClearTextureHostSync();
mActor->SendRemoveTexture();

View File

@ -282,7 +282,17 @@ public:
return gfx::SurfaceFormat::UNKNOWN;
}
virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() { return nullptr; }
/**
* This method is strictly for debugging. It causes locking and
* needless copies.
*/
virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() {
Lock(OpenMode::OPEN_READ);
RefPtr<gfx::SourceSurface> surf = BorrowDrawTarget()->Snapshot();
RefPtr<gfx::DataSourceSurface> data = surf->GetDataSurface();
Unlock();
return data;
}
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);

View File

@ -52,6 +52,12 @@ TiledLayerBufferComposite::TiledLayerBufferComposite(ISurfaceAllocator* aAllocat
mRetainedHeight = aDescriptor.retainedHeight();
mResolution = aDescriptor.resolution();
mFrameResolution = CSSToParentLayerScale(aDescriptor.frameResolution());
if (mResolution == 0 || IsNaN(mResolution)) {
// There are divisions by mResolution so this protects the compositor process
// against malicious content processes and fuzzing.
mIsValid = false;
return;
}
// Combine any valid content that wasn't already uploaded
nsIntRegion oldPaintedRegion(aOldPaintedRegion);

View File

@ -30,6 +30,14 @@ public:
void AddCompositorVsyncDispatcher(mozilla::CompositorVsyncDispatcher* aCompositorVsyncDispatcher);
void RemoveCompositorVsyncDispatcher(mozilla::CompositorVsyncDispatcher* aCompositorVsyncDispatcher);
// Notified when this display's vsync occurs, on the vsync thread
// The aVsyncTimestamp should normalize to the Vsync time that just occured
// However, different platforms give different vsync notification times.
// b2g - The vsync timestamp of the previous frame that was just displayed
// OSX - The vsync timestamp of the upcoming frame, in the future
// TODO: Windows / Linux. DOCUMENT THIS WHEN IMPLEMENTING ON THOSE PLATFORMS
// Android: TODO
// All platforms should normalize to the vsync that just occured.
// Large parts of Gecko assume TimeStamps should not be in the future such as animations
virtual void NotifyVsync(mozilla::TimeStamp aVsyncTimestamp);
// These should all only be called on the main thread

View File

@ -75,6 +75,7 @@ gfxDWriteFont::gfxDWriteFont(gfxFontEntry *aFontEntry,
: gfxFont(aFontEntry, aFontStyle, anAAOption)
, mCairoFontFace(nullptr)
, mMetrics(nullptr)
, mSpaceGlyph(0)
, mNeedsOblique(false)
, mNeedsBold(aNeedsBold)
, mUseSubpixelPositions(false)
@ -228,8 +229,15 @@ gfxDWriteFont::ComputeMetrics(AntialiasOption anAAOption)
mMetrics->internalLeading = std::max(mMetrics->maxHeight - mMetrics->emHeight, 0.0);
mMetrics->externalLeading = ceil(fontMetrics.lineGap * mFUnitsConvFactor);
UINT16 glyph = (uint16_t)GetSpaceGlyph();
mMetrics->spaceWidth = MeasureGlyphWidth(glyph);
UINT32 ucs = L' ';
UINT16 glyph;
HRESULT hr = mFontFace->GetGlyphIndicesA(&ucs, 1, &glyph);
if (FAILED(hr)) {
mMetrics->spaceWidth = 0;
} else {
mSpaceGlyph = glyph;
mMetrics->spaceWidth = MeasureGlyphWidth(glyph);
}
// try to get aveCharWidth from the OS/2 table, fall back to measuring 'x'
// if the table is not available or if using hinted/pixel-snapped widths
@ -251,7 +259,6 @@ gfxDWriteFont::ComputeMetrics(AntialiasOption anAAOption)
}
}
UINT32 ucs;
if (mMetrics->aveCharWidth < 1) {
ucs = L'x';
if (SUCCEEDED(mFontFace->GetGlyphIndicesA(&ucs, 1, &glyph))) {
@ -442,14 +449,7 @@ gfxDWriteFont::HasBitmapStrikeForSize(uint32_t aSize)
uint32_t
gfxDWriteFont::GetSpaceGlyph()
{
UINT32 ucs = L' ';
UINT16 glyph;
HRESULT hr;
hr = mFontFace->GetGlyphIndicesA(&ucs, 1, &glyph);
if (FAILED(hr)) {
return 0;
}
return glyph;
return mSpaceGlyph;
}
bool

View File

@ -98,6 +98,8 @@ protected:
// cache of glyph widths in 16.16 fixed-point pixels
nsAutoPtr<nsDataHashtable<nsUint32HashKey,int32_t> > mGlyphWidths;
uint32_t mSpaceGlyph;
bool mNeedsOblique;
bool mNeedsBold;
bool mUseSubpixelPositions;

View File

@ -116,7 +116,7 @@ gfxFT2FontBase::GetHorizontalMetrics()
if (MOZ_UNLIKELY(GetStyle()->size <= 0.0)) {
new(&mMetrics) gfxFont::Metrics(); // zero initialize
mSpaceGlyph = 0;
mSpaceGlyph = GetGlyph(' ');
} else {
gfxFT2LockedFace face(this);
face.GetMetrics(&mMetrics, &mSpaceGlyph);
@ -144,8 +144,6 @@ gfxFT2FontBase::GetHorizontalMetrics()
uint32_t
gfxFT2FontBase::GetSpaceGlyph()
{
NS_ASSERTION(GetStyle()->size != 0,
"forgot to short-circuit a text run with zero-sized font?");
GetHorizontalMetrics();
return mSpaceGlyph;
}

View File

@ -2114,6 +2114,23 @@ NeedsGlyphExtents(gfxFont *aFont, gfxTextRun *aTextRun)
aFont->GetFontEntry()->IsUserFont();
}
bool
gfxFont::IsSpaceGlyphInvisible(gfxContext *aRefContext, gfxTextRun *aTextRun)
{
if (!mFontEntry->mSpaceGlyphIsInvisibleInitialized &&
GetAdjustedSize() >= 1.0) {
gfxGlyphExtents *extents =
GetOrCreateGlyphExtents(aTextRun->GetAppUnitsPerDevUnit());
gfxRect glyphExtents;
mFontEntry->mSpaceGlyphIsInvisible =
extents->GetTightGlyphExtentsAppUnits(this, eHorizontal,
aRefContext, GetSpaceGlyph(), &glyphExtents) &&
glyphExtents.IsEmpty();
mFontEntry->mSpaceGlyphIsInvisibleInitialized = true;
}
return mFontEntry->mSpaceGlyphIsInvisible;
}
gfxFont::RunMetrics
gfxFont::Measure(gfxTextRun *aTextRun,
uint32_t aStart, uint32_t aEnd,
@ -2189,16 +2206,22 @@ gfxFont::Measure(gfxTextRun *aTextRun,
if (aSpacing) {
x += direction*aSpacing[0].mBefore;
}
uint32_t spaceGlyph = GetSpaceGlyph();
bool allGlyphsInvisible = true;
uint32_t i;
for (i = aStart; i < aEnd; ++i) {
const gfxTextRun::CompressedGlyph *glyphData = &charGlyphs[i];
if (glyphData->IsSimpleGlyph()) {
double advance = glyphData->GetSimpleAdvance();
uint32_t glyphIndex = glyphData->GetSimpleGlyph();
if (glyphIndex != spaceGlyph ||
!IsSpaceGlyphInvisible(aRefContext, aTextRun)) {
allGlyphsInvisible = false;
}
// Only get the real glyph horizontal extent if we were asked
// for the tight bounding box or we're in quality mode
if ((aBoundingBoxType != LOOSE_INK_EXTENTS || needsGlyphExtents) &&
extents) {
uint32_t glyphIndex = glyphData->GetSimpleGlyph();
extents){
uint16_t extentsWidth = extents->GetContainedGlyphWidthAppUnits(glyphIndex);
if (extentsWidth != gfxGlyphExtents::INVALID_WIDTH &&
aBoundingBoxType == LOOSE_INK_EXTENTS) {
@ -2221,6 +2244,7 @@ gfxFont::Measure(gfxTextRun *aTextRun,
}
x += direction*advance;
} else {
allGlyphsInvisible = false;
uint32_t glyphCount = glyphData->GetGlyphCount();
if (glyphCount > 0) {
const gfxTextRun::DetailedGlyph *details =
@ -2261,14 +2285,18 @@ gfxFont::Measure(gfxTextRun *aTextRun,
}
}
if (aBoundingBoxType == LOOSE_INK_EXTENTS) {
UnionRange(x, &advanceMin, &advanceMax);
gfxRect fontBox(advanceMin, -metrics.mAscent,
advanceMax - advanceMin, metrics.mAscent + metrics.mDescent);
metrics.mBoundingBox = metrics.mBoundingBox.Union(fontBox);
}
if (isRTL) {
metrics.mBoundingBox -= gfxPoint(x, 0);
if (allGlyphsInvisible) {
metrics.mBoundingBox.SetEmpty();
} else {
if (aBoundingBoxType == LOOSE_INK_EXTENTS) {
UnionRange(x, &advanceMin, &advanceMax);
gfxRect fontBox(advanceMin, -metrics.mAscent,
advanceMax - advanceMin, metrics.mAscent + metrics.mDescent);
metrics.mBoundingBox = metrics.mBoundingBox.Union(fontBox);
}
if (isRTL) {
metrics.mBoundingBox -= gfxPoint(x, 0);
}
}
// If the font may be rendered with a fake-italic effect, we need to allow

View File

@ -1846,6 +1846,8 @@ protected:
return -1;
}
bool IsSpaceGlyphInvisible(gfxContext *aRefContext, gfxTextRun *aTextRun);
void AddGlyphChangeObserver(GlyphChangeObserver *aObserver);
void RemoveGlyphChangeObserver(GlyphChangeObserver *aObserver);

View File

@ -85,6 +85,8 @@ gfxFontEntry::gfxFontEntry() :
mHasSpaceFeaturesKerning(false),
mHasSpaceFeaturesNonKerning(false),
mSkipDefaultFeatureSpaceCheck(false),
mSpaceGlyphIsInvisible(false),
mSpaceGlyphIsInvisibleInitialized(false),
mCheckedForGraphiteTables(false),
mHasCmapTable(false),
mGrFaceInitialized(false),
@ -120,6 +122,8 @@ gfxFontEntry::gfxFontEntry(const nsAString& aName, bool aIsStandardFace) :
mHasSpaceFeaturesKerning(false),
mHasSpaceFeaturesNonKerning(false),
mSkipDefaultFeatureSpaceCheck(false),
mSpaceGlyphIsInvisible(false),
mSpaceGlyphIsInvisibleInitialized(false),
mCheckedForGraphiteTables(false),
mHasCmapTable(false),
mGrFaceInitialized(false),

View File

@ -403,6 +403,8 @@ public:
bool mHasSpaceFeaturesKerning : 1;
bool mHasSpaceFeaturesNonKerning : 1;
bool mSkipDefaultFeatureSpaceCheck : 1;
bool mSpaceGlyphIsInvisible : 1;
bool mSpaceGlyphIsInvisibleInitialized : 1;
bool mHasGraphiteTables : 1;
bool mCheckedForGraphiteTables : 1;
bool mHasCmapTable : 1;

View File

@ -418,14 +418,7 @@ static CVReturn VsyncCallback(CVDisplayLinkRef aDisplayLink,
const CVTimeStamp* aOutputTime,
CVOptionFlags aFlagsIn,
CVOptionFlags* aFlagsOut,
void* aDisplayLinkContext)
{
VsyncSource::Display* display = (VsyncSource::Display*) aDisplayLinkContext;
int64_t timestamp = aOutputTime->hostTime;
mozilla::TimeStamp vsyncTime = mozilla::TimeStamp::FromSystemTime(timestamp);
display->NotifyVsync(vsyncTime);
return kCVReturnSuccess;
}
void* aDisplayLinkContext);
class OSXVsyncSource MOZ_FINAL : public VsyncSource
{
@ -439,7 +432,6 @@ public:
return mGlobalDisplay;
}
protected:
class OSXDisplay MOZ_FINAL : public VsyncSource::Display
{
public:
@ -471,6 +463,7 @@ protected:
return;
}
mPreviousTimestamp = TimeStamp::Now();
if (CVDisplayLinkStart(mDisplayLink) != kCVReturnSuccess) {
NS_WARNING("Could not activate the display link");
mDisplayLink = nullptr;
@ -494,6 +487,13 @@ protected:
return mDisplayLink != nullptr;
}
// The vsync timestamps given by the CVDisplayLinkCallback are
// in the future for the NEXT frame. Large parts of Gecko, such
// as animations assume a timestamp at either now or in the past.
// Normalize the timestamps given to the VsyncDispatchers to the vsync
// that just occured, not the vsync that is upcoming.
TimeStamp mPreviousTimestamp;
private:
// Manages the display link render thread
CVDisplayLinkRef mDisplayLink;
@ -507,6 +507,26 @@ private:
OSXDisplay mGlobalDisplay;
}; // OSXVsyncSource
static CVReturn VsyncCallback(CVDisplayLinkRef aDisplayLink,
const CVTimeStamp* aNow,
const CVTimeStamp* aOutputTime,
CVOptionFlags aFlagsIn,
CVOptionFlags* aFlagsOut,
void* aDisplayLinkContext)
{
// Executed on OS X hardware vsync thread
OSXVsyncSource::OSXDisplay* display = (OSXVsyncSource::OSXDisplay*) aDisplayLinkContext;
int64_t nextVsyncTimestamp = aOutputTime->hostTime;
mozilla::TimeStamp nextVsync = mozilla::TimeStamp::FromSystemTime(nextVsyncTimestamp);
mozilla::TimeStamp previousVsync = display->mPreviousTimestamp;
display->mPreviousTimestamp = nextVsync;
MOZ_ASSERT(TimeStamp::Now() > previousVsync);
display->NotifyVsync(previousVsync);
return kCVReturnSuccess;
}
already_AddRefed<mozilla::gfx::VsyncSource>
gfxPlatformMac::CreateHardwareVsyncSource()
{

View File

@ -38,15 +38,9 @@ if CONFIG['INTEL_ARCHITECTURE']:
if CONFIG['_MSC_VER']:
if CONFIG['OS_TEST'] == 'x86_64':
if CONFIG['_MSC_VER'] == '1400':
# VC8 doesn't support some SSE2 built-in functions
SOURCES += [
'yuv_row_win.cpp',
]
else:
SOURCES += [
'yuv_row_win64.cpp',
]
SOURCES += [
'yuv_row_win64.cpp',
]
else:
SOURCES += [
'yuv_row_win.cpp',

View File

@ -570,7 +570,7 @@ public:
return true;
}
void Notify(const NetworkInformation& aNetworkInfo) {
void Notify(const NetworkInformation& aNetworkInfo) MOZ_OVERRIDE {
unused << SendNotifyNetworkChange(aNetworkInfo);
}
@ -612,7 +612,7 @@ public:
return true;
}
void Notify(const ScreenConfiguration& aScreenConfiguration) {
void Notify(const ScreenConfiguration& aScreenConfiguration) MOZ_OVERRIDE {
unused << SendNotifyScreenConfigurationChange(aScreenConfiguration);
}
@ -778,7 +778,7 @@ public:
return true;
}
void Notify(const SensorData& aSensorData) {
void Notify(const SensorData& aSensorData) MOZ_OVERRIDE {
unused << SendNotifySensorChange(aSensorData);
}
@ -817,7 +817,7 @@ public:
return true;
}
void Notify(const WakeLockInformation& aWakeLockInfo)
void Notify(const WakeLockInformation& aWakeLockInfo) MOZ_OVERRIDE
{
unused << SendNotifyWakeLockChange(aWakeLockInfo);
}
@ -837,7 +837,7 @@ public:
return true;
}
void Notify(const SwitchEvent& aSwitchEvent)
void Notify(const SwitchEvent& aSwitchEvent) MOZ_OVERRIDE
{
unused << SendNotifySwitchChange(aSwitchEvent);
}
@ -850,12 +850,12 @@ public:
return true;
}
void Notify(const int64_t& aClockDeltaMS)
void Notify(const int64_t& aClockDeltaMS) MOZ_OVERRIDE
{
unused << SendNotifySystemClockChange(aClockDeltaMS);
}
void Notify(const SystemTimezoneChangeInformation& aSystemTimezoneChangeInfo)
void Notify(const SystemTimezoneChangeInformation& aSystemTimezoneChangeInfo) MOZ_OVERRIDE
{
unused << SendNotifySystemTimezoneChange(aSystemTimezoneChangeInfo);
}
@ -938,14 +938,14 @@ public:
}
virtual bool
RecvNotifySystemClockChange(const int64_t& aClockDeltaMS) {
RecvNotifySystemClockChange(const int64_t& aClockDeltaMS) MOZ_OVERRIDE {
hal::NotifySystemClockChange(aClockDeltaMS);
return true;
}
virtual bool
RecvNotifySystemTimezoneChange(
const SystemTimezoneChangeInformation& aSystemTimezoneChangeInfo) {
const SystemTimezoneChangeInformation& aSystemTimezoneChangeInfo) MOZ_OVERRIDE {
hal::NotifySystemTimezoneChange(aSystemTimezoneChangeInfo);
return true;
}

View File

@ -18,7 +18,7 @@ class NextPartObserver : public IProgressObserver
{
public:
MOZ_DECLARE_REFCOUNTED_TYPENAME(NextPartObserver)
NS_INLINE_DECL_REFCOUNTING(NextPartObserver)
NS_INLINE_DECL_REFCOUNTING(NextPartObserver, MOZ_OVERRIDE)
explicit NextPartObserver(MultipartImage* aOwner)
: mOwner(aOwner)

View File

@ -68,33 +68,11 @@ static const PRUint32 H256[8] = {
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
};
#if (_MSC_VER >= 1300)
#if defined(_MSC_VER)
#include <stdlib.h>
#pragma intrinsic(_byteswap_ulong)
#define SHA_HTONL(x) _byteswap_ulong(x)
#define BYTESWAP4(x) x = SHA_HTONL(x)
#elif defined(_MSC_VER) && defined(NSS_X86_OR_X64)
#ifndef FORCEINLINE
#if (_MSC_VER >= 1200)
#define FORCEINLINE __forceinline
#else
#define FORCEINLINE __inline
#endif
#endif
#define FASTCALL __fastcall
static FORCEINLINE PRUint32 FASTCALL
swap4b(PRUint32 dwd)
{
__asm {
mov eax,dwd
bswap eax
}
}
#define SHA_HTONL(x) swap4b(x)
#define BYTESWAP4(x) x = SHA_HTONL(x)
#elif defined(__GNUC__) && defined(NSS_X86_OR_X64)
static __inline__ PRUint32 swap4b(PRUint32 value)
{

View File

@ -1452,8 +1452,8 @@ ScanTypeObject(GCMarker *gcmarker, types::TypeObject *type)
if (TypeDescr *descr = type->maybeTypeDescr())
PushMarkStack(gcmarker, descr);
if (type->interpretedFunction)
PushMarkStack(gcmarker, type->interpretedFunction);
if (JSFunction *fun = type->maybeInterpretedFunction())
PushMarkStack(gcmarker, fun);
}
static void
@ -1480,8 +1480,10 @@ gc::MarkChildren(JSTracer *trc, types::TypeObject *type)
type->setTypeDescr(&descr->as<TypeDescr>());
}
if (type->interpretedFunction)
MarkObject(trc, &type->interpretedFunction, "type_function");
if (JSObject *fun = type->maybeInterpretedFunction()) {
MarkObjectUnbarriered(trc, &fun, "type_function");
type->setInterpretedFunction(&fun->as<JSFunction>());
}
}
static void

View File

@ -281,6 +281,9 @@ class BaselineFrame
void setPrevUpToDate() {
flags_ |= PREV_UP_TO_DATE;
}
void unsetPrevUpToDate() {
flags_ &= ~PREV_UP_TO_DATE;
}
bool isDebuggee() const {
return flags_ & DEBUGGEE;

View File

@ -296,12 +296,13 @@ IonBuilder::getPolyCallTargets(types::TemporaryTypeSet *calleeTypes, bool constr
if (!obj) {
types::TypeObject *typeObj = calleeTypes->getTypeObject(i);
MOZ_ASSERT(typeObj);
if (!typeObj->interpretedFunction) {
obj = typeObj->maybeInterpretedFunction();
if (!obj) {
targets.clear();
return true;
}
obj = typeObj->interpretedFunction;
*gotLambda = true;
}

View File

@ -2963,7 +2963,7 @@ class MSimdBox
return initialHeap_;
}
AliasSet getAliasSet() const {
AliasSet getAliasSet() const MOZ_OVERRIDE {
return AliasSet::None();
}
};

View File

@ -76,6 +76,9 @@ class RematerializedFrame
void setPrevUpToDate() {
prevUpToDate_ = true;
}
void unsetPrevUpToDate() {
prevUpToDate_ = false;
}
bool isDebuggee() const {
return isDebuggee_;

View File

@ -870,7 +870,7 @@ CreateFunctionPrototype(JSContext *cx, JSProtoKey key)
if (!protoType)
return nullptr;
protoType->interpretedFunction = functionProto;
protoType->setInterpretedFunction(functionProto);
script->setFunction(functionProto);
/*

View File

@ -3344,7 +3344,7 @@ TypeObject::print()
fprintf(stderr, " noLengthOverflow");
if (hasAnyFlags(OBJECT_FLAG_ITERATED))
fprintf(stderr, " iterated");
if (interpretedFunction)
if (maybeInterpretedFunction())
fprintf(stderr, " ifun");
}
@ -3749,7 +3749,7 @@ JSFunction::setTypeForScriptedFunction(ExclusiveContext *cx, HandleFunction fun,
return false;
fun->setType(type);
type->interpretedFunction = fun;
type->setInterpretedFunction(fun);
}
return true;
@ -4319,7 +4319,7 @@ JSObject::makeLazyType(JSContext *cx, HandleObject obj)
type->initSingleton(obj);
if (obj->is<JSFunction>() && obj->as<JSFunction>().isInterpreted())
type->interpretedFunction = &obj->as<JSFunction>();
type->setInterpretedFunction(&obj->as<JSFunction>());
obj->type_ = type;
@ -4950,12 +4950,14 @@ TypeObject::fixupAfterMovingGC()
if (IsForwarded(&typeDescr()))
addendum_ = Forwarded(&typeDescr());
break;
case Addendum_InterpretedFunction:
if (IsForwarded(maybeInterpretedFunction()))
addendum_ = Forwarded(maybeInterpretedFunction());
break;
default:
MOZ_CRASH();
}
}
if (interpretedFunction && IsForwarded(interpretedFunction.get()))
interpretedFunction = Forwarded(interpretedFunction.get());
}
#endif // JSGC_COMPACTING

View File

@ -513,13 +513,13 @@ enum MOZ_ENUM_TYPE(uint32_t) {
| OBJECT_FLAG_SETS_MARKED_UNKNOWN,
// Mask/shift for the kind of addendum attached to this type object.
OBJECT_FLAG_ADDENDUM_MASK = 0x04000000,
OBJECT_FLAG_ADDENDUM_MASK = 0x0c000000,
OBJECT_FLAG_ADDENDUM_SHIFT = 26,
// Mask/shift for this type object's generation. If out of sync with the
// TypeZone's generation, this TypeObject hasn't been swept yet.
OBJECT_FLAG_GENERATION_MASK = 0x08000000,
OBJECT_FLAG_GENERATION_SHIFT = 27,
OBJECT_FLAG_GENERATION_MASK = 0x10000000,
OBJECT_FLAG_GENERATION_SHIFT = 28,
};
typedef uint32_t TypeObjectFlags;
@ -1107,8 +1107,19 @@ struct TypeObject : public gc::TenuredCell
/* Flags for this object. */
TypeObjectFlags flags_;
// Kinds of addendums which can be attached to TypeObjects.
enum AddendumKind {
Addendum_None,
// When used by interpreted function, the addendum stores the
// canonical JSFunction object.
Addendum_InterpretedFunction,
// When used by the 'new' type when constructing an interpreted
// function, the addendum stores a TypeNewScript.
Addendum_NewScript,
// When used by typed objects, the addendum stores a TypeDescr.
Addendum_TypeDescr
};
@ -1172,6 +1183,18 @@ struct TypeObject : public gc::TenuredCell
setAddendum(Addendum_TypeDescr, descr);
}
JSFunction *maybeInterpretedFunction() {
// Note: as with type descriptors, there is no need to sweep when
// accessing the interpreted function associated with an object.
if (addendumKind() == Addendum_InterpretedFunction)
return reinterpret_cast<JSFunction *>(addendum_);
return nullptr;
}
void setInterpretedFunction(JSFunction *fun) {
setAddendum(Addendum_InterpretedFunction, fun);
}
private:
/*
* Properties of this object. This may contain JSID_VOID, representing the
@ -1217,13 +1240,6 @@ struct TypeObject : public gc::TenuredCell
Property **propertySet;
public:
/* If this is an interpreted function, the function object. */
HeapPtrFunction interpretedFunction;
#if JS_BITS_PER_WORD == 32
uint32_t padding;
#endif
inline TypeObject(const Class *clasp, TaggedProto proto, TypeObjectFlags initialFlags);
bool hasAnyFlags(TypeObjectFlags flags) {

View File

@ -761,14 +761,14 @@ ToUpperCase(JSContext *cx, JSLinearString *str)
return nullptr;
ToUpperCaseImpl(buf.get(), chars, i, length);
newChars.construct<Latin1CharPtr>(buf);
newChars.construct<Latin1CharPtr>(Move(buf));
} else {
TwoByteCharPtr buf = cx->make_pod_array<char16_t>(length + 1);
if (!buf)
return nullptr;
ToUpperCaseImpl(buf.get(), chars, i, length);
newChars.construct<TwoByteCharPtr>(buf);
newChars.construct<TwoByteCharPtr>(Move(buf));
}
}

View File

@ -2384,6 +2384,31 @@ DebugScopes::hasLiveScope(ScopeObject &scope)
return nullptr;
}
/* static */ void
DebugScopes::unsetPrevUpToDateUntil(JSContext *cx, AbstractFramePtr until)
{
// This is the one exception where fp->prevUpToDate() is cleared without
// popping the frame. When a frame is rematerialized, all frames younger
// than the rematerialized frame have their prevUpToDate set to
// false. This is because unrematerialized Ion frames have no usable
// AbstractFramePtr, and so are skipped by the updateLiveScopes. If in the
// future a frame suddenly gains a usable AbstractFramePtr via
// rematerialization, the prevUpToDate invariant will no longer hold.
for (AllFramesIter i(cx); !i.done(); ++i) {
if (!i.hasUsableAbstractFramePtr())
continue;
AbstractFramePtr frame = i.abstractFramePtr();
if (frame == until)
return;
if (frame.scopeChain()->compartment() != cx->compartment())
continue;
frame.unsetPrevUpToDate();
}
}
/* static */ void
DebugScopes::forwardLiveFrame(JSContext *cx, AbstractFramePtr from, AbstractFramePtr to)
{

View File

@ -942,6 +942,7 @@ class DebugScopes
static bool updateLiveScopes(JSContext *cx);
static ScopeIterVal *hasLiveScope(ScopeObject &scope);
static void unsetPrevUpToDateUntil(JSContext *cx, AbstractFramePtr frame);
// When a frame bails out from Ion to Baseline, there might be missing
// scopes keyed on, and live scopes containing, the old

View File

@ -775,6 +775,20 @@ AbstractFramePtr::setPrevUpToDate() const
asRematerializedFrame()->setPrevUpToDate();
}
inline void
AbstractFramePtr::unsetPrevUpToDate() const
{
if (isInterpreterFrame()) {
asInterpreterFrame()->unsetPrevUpToDate();
return;
}
if (isBaselineFrame()) {
asBaselineFrame()->unsetPrevUpToDate();
return;
}
asRematerializedFrame()->unsetPrevUpToDate();
}
inline Value &
AbstractFramePtr::thisValue() const
{

View File

@ -1477,8 +1477,6 @@ jit::JitActivation::clearRematerializedFrames()
jit::RematerializedFrame *
jit::JitActivation::getRematerializedFrame(JSContext *cx, const JitFrameIterator &iter, size_t inlineDepth)
{
// Only allow rematerializing from the same thread.
MOZ_ASSERT(cx->perThreadData == cx_->perThreadData);
MOZ_ASSERT(iter.activation() == this);
MOZ_ASSERT(iter.isIonScripted());
@ -1515,6 +1513,10 @@ jit::JitActivation::getRematerializedFrame(JSContext *cx, const JitFrameIterator
{
return nullptr;
}
// All frames younger than the rematerialized frame need to have their
// prevUpToDate flag cleared.
DebugScopes::unsetPrevUpToDateUntil(cx, p->value()[inlineDepth]);
}
return p->value()[inlineDepth];

View File

@ -217,6 +217,7 @@ class AbstractFramePtr
inline bool prevUpToDate() const;
inline void setPrevUpToDate() const;
inline void unsetPrevUpToDate() const;
inline bool isDebuggee() const;
inline void setIsDebuggee();
@ -833,6 +834,10 @@ class InterpreterFrame
flags_ |= PREV_UP_TO_DATE;
}
void unsetPrevUpToDate() {
flags_ &= ~PREV_UP_TO_DATE;
}
bool isDebuggee() const {
return !!(flags_ & DEBUGGEE);
}

View File

@ -1,24 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=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/. */
/* states and methods used while laying out a ruby segment */
#include "RubyReflowState.h"
using namespace mozilla;
RubyReflowState::RubyReflowState(
WritingMode aLineWM,
const nsTArray<nsRubyTextContainerFrame*>& aTextContainers)
: mCurrentContainerIndex(kBaseContainerIndex)
{
uint32_t rtcCount = aTextContainers.Length();
mTextContainers.SetCapacity(rtcCount);
for (uint32_t i = 0; i < rtcCount; i++) {
mTextContainers.AppendElement(
TextContainerInfo(aLineWM, aTextContainers[i]));
}
}

View File

@ -1,68 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=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/. */
/* states and methods used while laying out a ruby segment */
#ifndef mozilla_RubyReflowState_h_
#define mozilla_RubyReflowState_h_
#include "mozilla/Attributes.h"
#include "WritingModes.h"
#include "nsTArray.h"
#define RTC_ARRAY_SIZE 1
class nsRubyTextContainerFrame;
namespace mozilla {
class MOZ_STACK_CLASS RubyReflowState MOZ_FINAL
{
public:
explicit RubyReflowState(
WritingMode aLineWM,
const nsTArray<nsRubyTextContainerFrame*>& aTextContainers);
struct TextContainerInfo
{
nsRubyTextContainerFrame* mFrame;
LogicalSize mLineSize;
TextContainerInfo(WritingMode aLineWM, nsRubyTextContainerFrame* aFrame)
: mFrame(aFrame)
, mLineSize(aLineWM) { }
};
void AdvanceCurrentContainerIndex() { mCurrentContainerIndex++; }
void SetTextContainerInfo(int32_t aIndex,
nsRubyTextContainerFrame* aContainer,
const LogicalSize& aLineSize)
{
MOZ_ASSERT(mTextContainers[aIndex].mFrame == aContainer);
mTextContainers[aIndex].mLineSize = aLineSize;
}
const TextContainerInfo&
GetCurrentTextContainerInfo(nsRubyTextContainerFrame* aFrame) const
{
MOZ_ASSERT(mTextContainers[mCurrentContainerIndex].mFrame == aFrame);
return mTextContainers[mCurrentContainerIndex];
}
private:
static MOZ_CONSTEXPR_VAR int32_t kBaseContainerIndex = -1;
// The index of the current reflowing container. When it equals to
// kBaseContainerIndex, we are reflowing ruby base. Otherwise, it
// stands for the index of text containers in the ruby segment.
int32_t mCurrentContainerIndex;
nsAutoTArray<TextContainerInfo, RTC_ARRAY_SIZE> mTextContainers;
};
}
#endif // mozilla_RubyReflowState_h_

Some files were not shown because too many files have changed in this diff Show More