mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
merge mozilla-inbound to mozilla-central a=merge
This commit is contained in:
commit
e16a3cf28b
@ -322,6 +322,7 @@ pref("media.fragmented-mp4.gonk.enabled", true);
|
|||||||
pref("media.video-queue.default-size", 3);
|
pref("media.video-queue.default-size", 3);
|
||||||
|
|
||||||
// optimize images' memory usage
|
// optimize images' memory usage
|
||||||
|
pref("image.downscale-during-decode.enabled", true);
|
||||||
pref("image.mem.decodeondraw", true);
|
pref("image.mem.decodeondraw", true);
|
||||||
pref("image.mem.allow_locking_in_content_processes", false); /* don't allow image locking */
|
pref("image.mem.allow_locking_in_content_processes", false); /* don't allow image locking */
|
||||||
// Limit the surface cache to 1/8 of main memory or 128MB, whichever is smaller.
|
// Limit the surface cache to 1/8 of main memory or 128MB, whichever is smaller.
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
to { transform: translate(100px) }
|
to { transform: translate(100px) }
|
||||||
}
|
}
|
||||||
.target {
|
.target {
|
||||||
// Element needs geometry to be eligible for layerization
|
/* Element needs geometry to be eligible for layerization */
|
||||||
width: 100px;
|
width: 100px;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
|
@ -22,4 +22,3 @@ skip-if = buildapp == 'mulet'
|
|||||||
[css-transitions/test_element-get-animation-players.html]
|
[css-transitions/test_element-get-animation-players.html]
|
||||||
skip-if = buildapp == 'mulet'
|
skip-if = buildapp == 'mulet'
|
||||||
[mozilla/test_deferred_start.html]
|
[mozilla/test_deferred_start.html]
|
||||||
skip-if = buildapp == 'mulet' || buildapp == 'b2g' # bug 1113425, 1119981
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
to { transform: translate(100px); }
|
to { transform: translate(100px); }
|
||||||
}
|
}
|
||||||
.target {
|
.target {
|
||||||
// Element needs geometry to be eligible for layerization
|
/* Element needs geometry to be eligible for layerization */
|
||||||
width: 100px;
|
width: 100px;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
@ -60,13 +60,18 @@ async_test(function(t) {
|
|||||||
assert_unreached('ready promise was rejected');
|
assert_unreached('ready promise was rejected');
|
||||||
});
|
});
|
||||||
|
|
||||||
// We need to wait for up to two frames since the animation may not start
|
// We need to wait for up to three frames. This is because in some
|
||||||
// until the beginning of the next refresh driver tick and it won't queue
|
// cases it can take up to two frames for the initial layout
|
||||||
// the ready Promise callback until that point.
|
// to take place. Even after that happens we don't actually resolve the
|
||||||
}).then(waitForFrame).then(waitForFrame).then(t.step_func(function() {
|
// ready promise until the following tick.
|
||||||
|
})
|
||||||
|
.then(waitForFrame)
|
||||||
|
.then(waitForFrame)
|
||||||
|
.then(waitForFrame)
|
||||||
|
.then(t.step_func(function() {
|
||||||
assert_true(promiseCallbackDone,
|
assert_true(promiseCallbackDone,
|
||||||
'ready promise callback was called before the next'
|
'ready promise for an empty animation was resolved'
|
||||||
+ ' requestAnimationFrame callback');
|
+ ' within three animation frames');
|
||||||
t.done();
|
t.done();
|
||||||
}));
|
}));
|
||||||
}, 'AnimationPlayer.ready is resolved for an empty animation');
|
}, 'AnimationPlayer.ready is resolved for an empty animation');
|
||||||
|
@ -1832,7 +1832,7 @@ Element::IsLabelable() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Element::IsInteractiveHTMLContent() const
|
Element::IsInteractiveHTMLContent(bool aIgnoreTabindex) const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -276,7 +276,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Returns if the element is interactive content as per HTML specification.
|
* Returns if the element is interactive content as per HTML specification.
|
||||||
*/
|
*/
|
||||||
virtual bool IsInteractiveHTMLContent() const;
|
virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is the attribute named stored in the mapped attributes?
|
* Is the attribute named stored in the mapped attributes?
|
||||||
|
@ -74,6 +74,7 @@ EXPORTS += [
|
|||||||
'nsDOMNavigationTiming.h',
|
'nsDOMNavigationTiming.h',
|
||||||
'nsDOMString.h',
|
'nsDOMString.h',
|
||||||
'nsFocusManager.h',
|
'nsFocusManager.h',
|
||||||
|
'nsFormData.h',
|
||||||
'nsFrameMessageManager.h',
|
'nsFrameMessageManager.h',
|
||||||
'nsGenericDOMDataNode.h',
|
'nsGenericDOMDataNode.h',
|
||||||
'nsGkAtomList.h',
|
'nsGkAtomList.h',
|
||||||
|
55
dom/cache/TypeUtils.cpp
vendored
55
dom/cache/TypeUtils.cpp
vendored
@ -229,7 +229,7 @@ TypeUtils::ToPCacheResponseWithoutBody(PCacheResponse& aOut,
|
|||||||
|
|
||||||
aOut.status() = aIn.GetStatus();
|
aOut.status() = aIn.GetStatus();
|
||||||
aOut.statusText() = aIn.GetStatusText();
|
aOut.statusText() = aIn.GetStatusText();
|
||||||
nsRefPtr<InternalHeaders> headers = aIn.Headers();
|
nsRefPtr<InternalHeaders> headers = aIn.UnfilteredHeaders();
|
||||||
MOZ_ASSERT(headers);
|
MOZ_ASSERT(headers);
|
||||||
headers->GetPHeaders(aOut.headers());
|
headers->GetPHeaders(aOut.headers());
|
||||||
aOut.headersGuard() = headers->Guard();
|
aOut.headersGuard() = headers->Guard();
|
||||||
@ -278,37 +278,14 @@ TypeUtils::ToPCacheQueryParams(PCacheQueryParams& aOut,
|
|||||||
already_AddRefed<Response>
|
already_AddRefed<Response>
|
||||||
TypeUtils::ToResponse(const PCacheResponse& aIn)
|
TypeUtils::ToResponse(const PCacheResponse& aIn)
|
||||||
{
|
{
|
||||||
nsRefPtr<InternalResponse> ir;
|
if (aIn.type() == ResponseType::Error) {
|
||||||
switch (aIn.type())
|
nsRefPtr<InternalResponse> error = InternalResponse::NetworkError();
|
||||||
{
|
nsRefPtr<Response> r = new Response(GetGlobalObject(), error);
|
||||||
case ResponseType::Error:
|
return r.forget();
|
||||||
ir = InternalResponse::NetworkError();
|
|
||||||
break;
|
|
||||||
case ResponseType::Opaque:
|
|
||||||
ir = InternalResponse::OpaqueResponse();
|
|
||||||
break;
|
|
||||||
case ResponseType::Default:
|
|
||||||
ir = new InternalResponse(aIn.status(), aIn.statusText());
|
|
||||||
break;
|
|
||||||
case ResponseType::Basic:
|
|
||||||
{
|
|
||||||
nsRefPtr<InternalResponse> inner = new InternalResponse(aIn.status(),
|
|
||||||
aIn.statusText());
|
|
||||||
ir = InternalResponse::BasicResponse(inner);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ResponseType::Cors:
|
|
||||||
{
|
|
||||||
nsRefPtr<InternalResponse> inner = new InternalResponse(aIn.status(),
|
|
||||||
aIn.statusText());
|
|
||||||
ir = InternalResponse::CORSResponse(inner);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
MOZ_CRASH("Unexpected ResponseType!");
|
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(ir);
|
|
||||||
|
|
||||||
|
nsRefPtr<InternalResponse> ir = new InternalResponse(aIn.status(),
|
||||||
|
aIn.statusText());
|
||||||
ir->SetUrl(NS_ConvertUTF16toUTF8(aIn.url()));
|
ir->SetUrl(NS_ConvertUTF16toUTF8(aIn.url()));
|
||||||
|
|
||||||
nsRefPtr<InternalHeaders> internalHeaders =
|
nsRefPtr<InternalHeaders> internalHeaders =
|
||||||
@ -324,6 +301,24 @@ TypeUtils::ToResponse(const PCacheResponse& aIn)
|
|||||||
nsCOMPtr<nsIInputStream> stream = ReadStream::Create(aIn.body());
|
nsCOMPtr<nsIInputStream> stream = ReadStream::Create(aIn.body());
|
||||||
ir->SetBody(stream);
|
ir->SetBody(stream);
|
||||||
|
|
||||||
|
switch (aIn.type())
|
||||||
|
{
|
||||||
|
case ResponseType::Default:
|
||||||
|
break;
|
||||||
|
case ResponseType::Opaque:
|
||||||
|
ir = ir->OpaqueResponse();
|
||||||
|
break;
|
||||||
|
case ResponseType::Basic:
|
||||||
|
ir = ir->BasicResponse();
|
||||||
|
break;
|
||||||
|
case ResponseType::Cors:
|
||||||
|
ir = ir->CORSResponse();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
MOZ_CRASH("Unexpected ResponseType!");
|
||||||
|
}
|
||||||
|
MOZ_ASSERT(ir);
|
||||||
|
|
||||||
nsRefPtr<Response> ref = new Response(GetGlobalObject(), ir);
|
nsRefPtr<Response> ref = new Response(GetGlobalObject(), ir);
|
||||||
return ref.forget();
|
return ref.forget();
|
||||||
}
|
}
|
||||||
|
3
dom/cache/test/mochitest/driver.js
vendored
3
dom/cache/test/mochitest/driver.js
vendored
@ -81,8 +81,7 @@ function runTests(testFile, order) {
|
|||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
if (typeof order == "undefined") {
|
if (typeof order == "undefined") {
|
||||||
order = "sequential"; // sequential by default, see bug 1143222.
|
order = "both"; // both by default
|
||||||
// TODO: Make this "both".
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ok(order == "parallel" || order == "sequential" || order == "both",
|
ok(order == "parallel" || order == "sequential" || order == "both",
|
||||||
|
@ -18,7 +18,10 @@ function checkResponse(r, response, responseText) {
|
|||||||
is(r.statusText, response.statusText,
|
is(r.statusText, response.statusText,
|
||||||
"Both responses should have the same status text");
|
"Both responses should have the same status text");
|
||||||
return r.text().then(function(text) {
|
return r.text().then(function(text) {
|
||||||
is(text, responseText, "The response body should be correct");
|
// Avoid dumping out the large response text to the log if they're equal.
|
||||||
|
if (text !== responseText) {
|
||||||
|
is(text, responseText, "The response body should be correct");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,10 @@ function checkResponse(r) {
|
|||||||
is(r.statusText, response.statusText,
|
is(r.statusText, response.statusText,
|
||||||
"Both responses should have the same status text");
|
"Both responses should have the same status text");
|
||||||
return r.text().then(function(text) {
|
return r.text().then(function(text) {
|
||||||
is(text, responseText, "The response body should be correct");
|
// Avoid dumping out the large response text to the log if they're equal.
|
||||||
|
if (text !== responseText) {
|
||||||
|
is(text, responseText, "The response body should be correct");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "InternalRequest.h"
|
#include "InternalRequest.h"
|
||||||
#include "InternalResponse.h"
|
#include "InternalResponse.h"
|
||||||
|
|
||||||
|
#include "nsFormData.h"
|
||||||
#include "WorkerPrivate.h"
|
#include "WorkerPrivate.h"
|
||||||
#include "WorkerRunnable.h"
|
#include "WorkerRunnable.h"
|
||||||
#include "WorkerScope.h"
|
#include "WorkerScope.h"
|
||||||
@ -452,6 +453,16 @@ ExtractFromBlob(const File& aFile, nsIInputStream** aStream,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
ExtractFromFormData(nsFormData& aFormData, nsIInputStream** aStream,
|
||||||
|
nsCString& aContentType)
|
||||||
|
{
|
||||||
|
uint64_t unusedContentLength;
|
||||||
|
nsAutoCString unusedCharset;
|
||||||
|
return aFormData.GetSendInfo(aStream, &unusedContentLength,
|
||||||
|
aContentType, unusedCharset);
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
ExtractFromUSVString(const nsString& aStr,
|
ExtractFromUSVString(const nsString& aStr,
|
||||||
nsIInputStream** aStream,
|
nsIInputStream** aStream,
|
||||||
@ -502,7 +513,7 @@ ExtractFromURLSearchParams(const URLSearchParams& aParams,
|
|||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams& aBodyInit,
|
ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& aBodyInit,
|
||||||
nsIInputStream** aStream,
|
nsIInputStream** aStream,
|
||||||
nsCString& aContentType)
|
nsCString& aContentType)
|
||||||
{
|
{
|
||||||
@ -517,6 +528,9 @@ ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrUSVStr
|
|||||||
} else if (aBodyInit.IsBlob()) {
|
} else if (aBodyInit.IsBlob()) {
|
||||||
const File& blob = aBodyInit.GetAsBlob();
|
const File& blob = aBodyInit.GetAsBlob();
|
||||||
return ExtractFromBlob(blob, aStream, aContentType);
|
return ExtractFromBlob(blob, aStream, aContentType);
|
||||||
|
} else if (aBodyInit.IsFormData()) {
|
||||||
|
nsFormData& form = aBodyInit.GetAsFormData();
|
||||||
|
return ExtractFromFormData(form, aStream, aContentType);
|
||||||
} else if (aBodyInit.IsUSVString()) {
|
} else if (aBodyInit.IsUSVString()) {
|
||||||
nsAutoString str;
|
nsAutoString str;
|
||||||
str.Assign(aBodyInit.GetAsUSVString());
|
str.Assign(aBodyInit.GetAsUSVString());
|
||||||
@ -531,7 +545,7 @@ ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrUSVStr
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
ExtractByteStreamFromBody(const ArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams& aBodyInit,
|
ExtractByteStreamFromBody(const ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& aBodyInit,
|
||||||
nsIInputStream** aStream,
|
nsIInputStream** aStream,
|
||||||
nsCString& aContentType)
|
nsCString& aContentType)
|
||||||
{
|
{
|
||||||
@ -546,6 +560,9 @@ ExtractByteStreamFromBody(const ArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrU
|
|||||||
} else if (aBodyInit.IsBlob()) {
|
} else if (aBodyInit.IsBlob()) {
|
||||||
const File& blob = aBodyInit.GetAsBlob();
|
const File& blob = aBodyInit.GetAsBlob();
|
||||||
return ExtractFromBlob(blob, aStream, aContentType);
|
return ExtractFromBlob(blob, aStream, aContentType);
|
||||||
|
} else if (aBodyInit.IsFormData()) {
|
||||||
|
nsFormData& form = aBodyInit.GetAsFormData();
|
||||||
|
return ExtractFromFormData(form, aStream, aContentType);
|
||||||
} else if (aBodyInit.IsUSVString()) {
|
} else if (aBodyInit.IsUSVString()) {
|
||||||
nsAutoString str;
|
nsAutoString str;
|
||||||
str.Assign(aBodyInit.GetAsUSVString());
|
str.Assign(aBodyInit.GetAsUSVString());
|
||||||
|
@ -26,9 +26,9 @@ class nsIGlobalObject;
|
|||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
class ArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams;
|
class ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams;
|
||||||
class InternalRequest;
|
class InternalRequest;
|
||||||
class OwningArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams;
|
class OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams;
|
||||||
class RequestOrUSVString;
|
class RequestOrUSVString;
|
||||||
|
|
||||||
namespace workers {
|
namespace workers {
|
||||||
@ -48,7 +48,7 @@ UpdateRequestReferrer(nsIGlobalObject* aGlobal, InternalRequest* aRequest);
|
|||||||
* Stores content type in out param aContentType.
|
* Stores content type in out param aContentType.
|
||||||
*/
|
*/
|
||||||
nsresult
|
nsresult
|
||||||
ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams& aBodyInit,
|
ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& aBodyInit,
|
||||||
nsIInputStream** aStream,
|
nsIInputStream** aStream,
|
||||||
nsCString& aContentType);
|
nsCString& aContentType);
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrUSVStr
|
|||||||
* Non-owning version.
|
* Non-owning version.
|
||||||
*/
|
*/
|
||||||
nsresult
|
nsresult
|
||||||
ExtractByteStreamFromBody(const ArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams& aBodyInit,
|
ExtractByteStreamFromBody(const ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& aBodyInit,
|
||||||
nsIInputStream** aStream,
|
nsIInputStream** aStream,
|
||||||
nsCString& aContentType);
|
nsCString& aContentType);
|
||||||
|
|
||||||
|
@ -485,16 +485,24 @@ FetchDriver::HttpFetch(bool aCORSFlag, bool aCORSPreflightFlag, bool aAuthentica
|
|||||||
internalChan->ForceNoIntercept();
|
internalChan->ForceNoIntercept();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up a CORS proxy that will handle the various requirements of the CORS
|
nsCOMPtr<nsIStreamListener> listener = this;
|
||||||
// protocol. It handles the preflight cache and CORS response headers.
|
|
||||||
// If the request is allowed, it will start our original request
|
// Unless the cors mode is explicitly no-cors, we set up a cors proxy even in
|
||||||
// and our observer will be notified. On failure, our observer is notified
|
// the same-origin case, since the proxy does not enforce cors header checks
|
||||||
// directly.
|
// in the same-origin case.
|
||||||
nsRefPtr<nsCORSListenerProxy> corsListener =
|
if (mRequest->Mode() != RequestMode::No_cors) {
|
||||||
new nsCORSListenerProxy(this, mPrincipal, useCredentials);
|
// Set up a CORS proxy that will handle the various requirements of the CORS
|
||||||
rv = corsListener->Init(chan, true /* allow data uri */);
|
// protocol. It handles the preflight cache and CORS response headers.
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
// If the request is allowed, it will start our original request
|
||||||
return FailWithNetworkError();
|
// and our observer will be notified. On failure, our observer is notified
|
||||||
|
// directly.
|
||||||
|
nsRefPtr<nsCORSListenerProxy> corsListener =
|
||||||
|
new nsCORSListenerProxy(this, mPrincipal, useCredentials);
|
||||||
|
rv = corsListener->Init(chan, true /* allow data uri */);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return FailWithNetworkError();
|
||||||
|
}
|
||||||
|
listener = corsListener.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If preflight is required, start a "CORS preflight fetch"
|
// If preflight is required, start a "CORS preflight fetch"
|
||||||
@ -507,12 +515,12 @@ FetchDriver::HttpFetch(bool aCORSFlag, bool aCORSPreflightFlag, bool aAuthentica
|
|||||||
nsAutoTArray<nsCString, 5> unsafeHeaders;
|
nsAutoTArray<nsCString, 5> unsafeHeaders;
|
||||||
mRequest->Headers()->GetUnsafeHeaders(unsafeHeaders);
|
mRequest->Headers()->GetUnsafeHeaders(unsafeHeaders);
|
||||||
|
|
||||||
rv = NS_StartCORSPreflight(chan, corsListener, mPrincipal,
|
rv = NS_StartCORSPreflight(chan, listener, mPrincipal,
|
||||||
useCredentials,
|
useCredentials,
|
||||||
unsafeHeaders,
|
unsafeHeaders,
|
||||||
getter_AddRefs(preflightChannel));
|
getter_AddRefs(preflightChannel));
|
||||||
} else {
|
} else {
|
||||||
rv = chan->AsyncOpen(corsListener, nullptr);
|
rv = chan->AsyncOpen(listener, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
@ -548,13 +556,13 @@ FetchDriver::BeginAndGetFilteredResponse(InternalResponse* aResponse)
|
|||||||
nsRefPtr<InternalResponse> filteredResponse;
|
nsRefPtr<InternalResponse> filteredResponse;
|
||||||
switch (mRequest->GetResponseTainting()) {
|
switch (mRequest->GetResponseTainting()) {
|
||||||
case InternalRequest::RESPONSETAINT_BASIC:
|
case InternalRequest::RESPONSETAINT_BASIC:
|
||||||
filteredResponse = InternalResponse::BasicResponse(aResponse);
|
filteredResponse = aResponse->BasicResponse();
|
||||||
break;
|
break;
|
||||||
case InternalRequest::RESPONSETAINT_CORS:
|
case InternalRequest::RESPONSETAINT_CORS:
|
||||||
filteredResponse = InternalResponse::CORSResponse(aResponse);
|
filteredResponse = aResponse->CORSResponse();
|
||||||
break;
|
break;
|
||||||
case InternalRequest::RESPONSETAINT_OPAQUE:
|
case InternalRequest::RESPONSETAINT_OPAQUE:
|
||||||
filteredResponse = InternalResponse::OpaqueResponse();
|
filteredResponse = aResponse->OpaqueResponse();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
MOZ_CRASH("Unexpected case");
|
MOZ_CRASH("Unexpected case");
|
||||||
@ -775,7 +783,7 @@ FetchDriver::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
|
|||||||
if (!NS_IsInternalSameURIRedirect(aOldChannel, aNewChannel, aFlags)) {
|
if (!NS_IsInternalSameURIRedirect(aOldChannel, aNewChannel, aFlags)) {
|
||||||
rv = DoesNotRequirePreflight(aNewChannel);
|
rv = DoesNotRequirePreflight(aNewChannel);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
NS_WARNING("nsXMLHttpRequest::OnChannelRedirect: "
|
NS_WARNING("FetchDriver::OnChannelRedirect: "
|
||||||
"DoesNotRequirePreflight returned failure");
|
"DoesNotRequirePreflight returned failure");
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -23,25 +23,17 @@ InternalResponse::InternalResponse(uint16_t aStatus, const nsACString& aStatusTe
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Headers are not copied since BasicResponse and CORSResponse both need custom
|
|
||||||
// header handling. Body is not copied as it cannot be shared directly.
|
|
||||||
InternalResponse::InternalResponse(const InternalResponse& aOther)
|
|
||||||
: mType(aOther.mType)
|
|
||||||
, mTerminationReason(aOther.mTerminationReason)
|
|
||||||
, mURL(aOther.mURL)
|
|
||||||
, mFinalURL(aOther.mFinalURL)
|
|
||||||
, mStatus(aOther.mStatus)
|
|
||||||
, mStatusText(aOther.mStatusText)
|
|
||||||
, mContentType(aOther.mContentType)
|
|
||||||
, mSecurityInfo(aOther.mSecurityInfo)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<InternalResponse>
|
already_AddRefed<InternalResponse>
|
||||||
InternalResponse::Clone()
|
InternalResponse::Clone()
|
||||||
{
|
{
|
||||||
nsRefPtr<InternalResponse> clone = new InternalResponse(*this);
|
nsRefPtr<InternalResponse> clone = CreateIncompleteCopy();
|
||||||
|
|
||||||
clone->mHeaders = new InternalHeaders(*mHeaders);
|
clone->mHeaders = new InternalHeaders(*mHeaders);
|
||||||
|
if (mWrappedResponse) {
|
||||||
|
clone->mWrappedResponse = mWrappedResponse->Clone();
|
||||||
|
MOZ_ASSERT(!mBody);
|
||||||
|
return clone.forget();
|
||||||
|
}
|
||||||
|
|
||||||
if (!mBody) {
|
if (!mBody) {
|
||||||
return clone.forget();
|
return clone.forget();
|
||||||
@ -62,27 +54,25 @@ InternalResponse::Clone()
|
|||||||
return clone.forget();
|
return clone.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
|
||||||
already_AddRefed<InternalResponse>
|
already_AddRefed<InternalResponse>
|
||||||
InternalResponse::BasicResponse(InternalResponse* aInner)
|
InternalResponse::BasicResponse()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aInner);
|
MOZ_ASSERT(!mWrappedResponse, "Can't BasicResponse a already wrapped response");
|
||||||
nsRefPtr<InternalResponse> basic = new InternalResponse(*aInner);
|
nsRefPtr<InternalResponse> basic = CreateIncompleteCopy();
|
||||||
basic->mType = ResponseType::Basic;
|
basic->mType = ResponseType::Basic;
|
||||||
basic->mHeaders = InternalHeaders::BasicHeaders(aInner->mHeaders);
|
basic->mHeaders = InternalHeaders::BasicHeaders(Headers());
|
||||||
basic->mBody.swap(aInner->mBody);
|
basic->mWrappedResponse = this;
|
||||||
return basic.forget();
|
return basic.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
|
||||||
already_AddRefed<InternalResponse>
|
already_AddRefed<InternalResponse>
|
||||||
InternalResponse::CORSResponse(InternalResponse* aInner)
|
InternalResponse::CORSResponse()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aInner);
|
MOZ_ASSERT(!mWrappedResponse, "Can't CORSResponse a already wrapped response");
|
||||||
nsRefPtr<InternalResponse> cors = new InternalResponse(*aInner);
|
nsRefPtr<InternalResponse> cors = CreateIncompleteCopy();
|
||||||
cors->mType = ResponseType::Cors;
|
cors->mType = ResponseType::Cors;
|
||||||
cors->mHeaders = InternalHeaders::CORSHeaders(aInner->mHeaders);
|
cors->mHeaders = InternalHeaders::CORSHeaders(Headers());
|
||||||
cors->mBody.swap(aInner->mBody);
|
cors->mWrappedResponse = this;
|
||||||
return cors.forget();
|
return cors.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,27 +38,34 @@ public:
|
|||||||
return response.forget();
|
return response.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
static already_AddRefed<InternalResponse>
|
already_AddRefed<InternalResponse>
|
||||||
OpaqueResponse()
|
OpaqueResponse()
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(!mWrappedResponse, "Can't OpaqueResponse a already wrapped response");
|
||||||
nsRefPtr<InternalResponse> response = new InternalResponse(0, EmptyCString());
|
nsRefPtr<InternalResponse> response = new InternalResponse(0, EmptyCString());
|
||||||
response->mType = ResponseType::Opaque;
|
response->mType = ResponseType::Opaque;
|
||||||
|
response->mTerminationReason = mTerminationReason;
|
||||||
|
response->mURL = mURL;
|
||||||
|
response->mFinalURL = mFinalURL;
|
||||||
|
response->mSecurityInfo = mSecurityInfo;
|
||||||
|
response->mWrappedResponse = this;
|
||||||
return response.forget();
|
return response.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
// DO NOT use the inner response after filtering it since the filtered
|
already_AddRefed<InternalResponse>
|
||||||
// response will adopt the inner response's body.
|
BasicResponse();
|
||||||
static already_AddRefed<InternalResponse>
|
|
||||||
BasicResponse(InternalResponse* aInner);
|
|
||||||
|
|
||||||
// DO NOT use the inner response after filtering it since the filtered
|
already_AddRefed<InternalResponse>
|
||||||
// response will adopt the inner response's body.
|
CORSResponse();
|
||||||
static already_AddRefed<InternalResponse>
|
|
||||||
CORSResponse(InternalResponse* aInner);
|
|
||||||
|
|
||||||
ResponseType
|
ResponseType
|
||||||
Type() const
|
Type() const
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT_IF(mType == ResponseType::Error, !mWrappedResponse);
|
||||||
|
MOZ_ASSERT_IF(mType == ResponseType::Default, !mWrappedResponse);
|
||||||
|
MOZ_ASSERT_IF(mType == ResponseType::Basic, mWrappedResponse);
|
||||||
|
MOZ_ASSERT_IF(mType == ResponseType::Cors, mWrappedResponse);
|
||||||
|
MOZ_ASSERT_IF(mType == ResponseType::Opaque, mWrappedResponse);
|
||||||
return mType;
|
return mType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,9 +118,28 @@ public:
|
|||||||
return mHeaders;
|
return mHeaders;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InternalHeaders*
|
||||||
|
UnfilteredHeaders()
|
||||||
|
{
|
||||||
|
if (mWrappedResponse) {
|
||||||
|
return mWrappedResponse->Headers();
|
||||||
|
};
|
||||||
|
|
||||||
|
return Headers();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GetBody(nsIInputStream** aStream)
|
GetBody(nsIInputStream** aStream)
|
||||||
{
|
{
|
||||||
|
if (Type() == ResponseType::Opaque) {
|
||||||
|
*aStream = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mWrappedResponse) {
|
||||||
|
MOZ_ASSERT(!mBody);
|
||||||
|
return mWrappedResponse->GetBody(aStream);
|
||||||
|
}
|
||||||
nsCOMPtr<nsIInputStream> stream = mBody;
|
nsCOMPtr<nsIInputStream> stream = mBody;
|
||||||
stream.forget(aStream);
|
stream.forget(aStream);
|
||||||
}
|
}
|
||||||
@ -121,6 +147,9 @@ public:
|
|||||||
void
|
void
|
||||||
SetBody(nsIInputStream* aBody)
|
SetBody(nsIInputStream* aBody)
|
||||||
{
|
{
|
||||||
|
if (mWrappedResponse) {
|
||||||
|
return mWrappedResponse->SetBody(aBody);
|
||||||
|
}
|
||||||
// A request's body may not be reset once set.
|
// A request's body may not be reset once set.
|
||||||
MOZ_ASSERT(!mBody);
|
MOZ_ASSERT(!mBody);
|
||||||
mBody = aBody;
|
mBody = aBody;
|
||||||
@ -142,9 +171,22 @@ private:
|
|||||||
~InternalResponse()
|
~InternalResponse()
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
// Used to create filtered and cloned responses.
|
explicit InternalResponse(const InternalResponse& aOther) = delete;
|
||||||
// Does not copy headers or body stream.
|
InternalResponse& operator=(const InternalResponse&) = delete;
|
||||||
explicit InternalResponse(const InternalResponse& aOther);
|
|
||||||
|
// Returns an instance of InternalResponse which is a copy of this
|
||||||
|
// InternalResponse, except headers, body and wrapped response (if any) which
|
||||||
|
// are left uninitialized. Used for cloning and filtering.
|
||||||
|
already_AddRefed<InternalResponse> CreateIncompleteCopy()
|
||||||
|
{
|
||||||
|
nsRefPtr<InternalResponse> copy = new InternalResponse(mStatus, mStatusText);
|
||||||
|
copy->mType = mType;
|
||||||
|
copy->mTerminationReason = mTerminationReason;
|
||||||
|
copy->mURL = mURL;
|
||||||
|
copy->mFinalURL = mFinalURL;
|
||||||
|
copy->mSecurityInfo = mSecurityInfo;
|
||||||
|
return copy.forget();
|
||||||
|
}
|
||||||
|
|
||||||
ResponseType mType;
|
ResponseType mType;
|
||||||
nsCString mTerminationReason;
|
nsCString mTerminationReason;
|
||||||
@ -154,8 +196,13 @@ private:
|
|||||||
const nsCString mStatusText;
|
const nsCString mStatusText;
|
||||||
nsRefPtr<InternalHeaders> mHeaders;
|
nsRefPtr<InternalHeaders> mHeaders;
|
||||||
nsCOMPtr<nsIInputStream> mBody;
|
nsCOMPtr<nsIInputStream> mBody;
|
||||||
nsCString mContentType;
|
|
||||||
nsCString mSecurityInfo;
|
nsCString mSecurityInfo;
|
||||||
|
|
||||||
|
// For filtered responses.
|
||||||
|
// Cache, and SW interception should always serialize/access the underlying
|
||||||
|
// unfiltered headers and when deserializing, create an InternalResponse
|
||||||
|
// with the unfiltered headers followed by wrapping it.
|
||||||
|
nsRefPtr<InternalResponse> mWrappedResponse;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
@ -228,7 +228,7 @@ Request::Constructor(const GlobalObject& aGlobal,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const OwningArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams& bodyInit = aInit.mBody.Value();
|
const OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& bodyInit = aInit.mBody.Value();
|
||||||
nsCOMPtr<nsIInputStream> stream;
|
nsCOMPtr<nsIInputStream> stream;
|
||||||
nsCString contentType;
|
nsCString contentType;
|
||||||
aRv = ExtractByteStreamFromBody(bodyInit,
|
aRv = ExtractByteStreamFromBody(bodyInit,
|
||||||
|
@ -99,7 +99,7 @@ Response::Redirect(const GlobalObject& aGlobal, const nsAString& aUrl,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<ArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams> body;
|
Optional<ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams> body;
|
||||||
ResponseInit init;
|
ResponseInit init;
|
||||||
init.mStatus = aStatus;
|
init.mStatus = aStatus;
|
||||||
nsRefPtr<Response> r = Response::Constructor(aGlobal, body, init, aRv);
|
nsRefPtr<Response> r = Response::Constructor(aGlobal, body, init, aRv);
|
||||||
@ -120,7 +120,7 @@ Response::Redirect(const GlobalObject& aGlobal, const nsAString& aUrl,
|
|||||||
|
|
||||||
/*static*/ already_AddRefed<Response>
|
/*static*/ already_AddRefed<Response>
|
||||||
Response::Constructor(const GlobalObject& aGlobal,
|
Response::Constructor(const GlobalObject& aGlobal,
|
||||||
const Optional<ArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams>& aBody,
|
const Optional<ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams>& aBody,
|
||||||
const ResponseInit& aInit, ErrorResult& aRv)
|
const ResponseInit& aInit, ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
if (aInit.mStatus < 200 || aInit.mStatus > 599) {
|
if (aInit.mStatus < 200 || aInit.mStatus > 599) {
|
||||||
|
@ -103,7 +103,7 @@ public:
|
|||||||
|
|
||||||
static already_AddRefed<Response>
|
static already_AddRefed<Response>
|
||||||
Constructor(const GlobalObject& aGlobal,
|
Constructor(const GlobalObject& aGlobal,
|
||||||
const Optional<ArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams>& aBody,
|
const Optional<ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams>& aBody,
|
||||||
const ResponseInit& aInit, ErrorResult& rv);
|
const ResponseInit& aInit, ErrorResult& rv);
|
||||||
|
|
||||||
nsIGlobalObject* GetParentObject() const
|
nsIGlobalObject* GetParentObject() const
|
||||||
|
@ -43,7 +43,7 @@ public:
|
|||||||
virtual bool Draggable() const MOZ_OVERRIDE;
|
virtual bool Draggable() const MOZ_OVERRIDE;
|
||||||
|
|
||||||
// Element
|
// Element
|
||||||
virtual bool IsInteractiveHTMLContent() const MOZ_OVERRIDE
|
virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const MOZ_OVERRIDE
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ HTMLAudioElement::~HTMLAudioElement()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HTMLAudioElement::IsInteractiveHTMLContent() const
|
HTMLAudioElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const
|
||||||
{
|
{
|
||||||
return HasAttr(kNameSpaceID_None, nsGkAtoms::controls);
|
return HasAttr(kNameSpaceID_None, nsGkAtoms::controls);
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ public:
|
|||||||
explicit HTMLAudioElement(already_AddRefed<NodeInfo>& aNodeInfo);
|
explicit HTMLAudioElement(already_AddRefed<NodeInfo>& aNodeInfo);
|
||||||
|
|
||||||
// Element
|
// Element
|
||||||
virtual bool IsInteractiveHTMLContent() const MOZ_OVERRIDE;
|
virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const MOZ_OVERRIDE;
|
||||||
|
|
||||||
// nsIDOMHTMLMediaElement
|
// nsIDOMHTMLMediaElement
|
||||||
using HTMLMediaElement::GetPaused;
|
using HTMLMediaElement::GetPaused;
|
||||||
|
@ -37,7 +37,7 @@ public:
|
|||||||
NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLButtonElement, button)
|
NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLButtonElement, button)
|
||||||
|
|
||||||
// Element
|
// Element
|
||||||
virtual bool IsInteractiveHTMLContent() const MOZ_OVERRIDE
|
virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const MOZ_OVERRIDE
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ public:
|
|||||||
NS_DECL_ISUPPORTS_INHERITED
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
|
||||||
// Element
|
// Element
|
||||||
virtual bool IsInteractiveHTMLContent() const MOZ_OVERRIDE
|
virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const MOZ_OVERRIDE
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,7 @@ NS_IMPL_STRING_ATTR(HTMLImageElement, UseMap, usemap)
|
|||||||
NS_IMPL_INT_ATTR(HTMLImageElement, Vspace, vspace)
|
NS_IMPL_INT_ATTR(HTMLImageElement, Vspace, vspace)
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HTMLImageElement::IsInteractiveHTMLContent() const
|
HTMLImageElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const
|
||||||
{
|
{
|
||||||
return HasAttr(kNameSpaceID_None, nsGkAtoms::usemap);
|
return HasAttr(kNameSpaceID_None, nsGkAtoms::usemap);
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ public:
|
|||||||
virtual bool Draggable() const MOZ_OVERRIDE;
|
virtual bool Draggable() const MOZ_OVERRIDE;
|
||||||
|
|
||||||
// Element
|
// Element
|
||||||
virtual bool IsInteractiveHTMLContent() const MOZ_OVERRIDE;
|
virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const MOZ_OVERRIDE;
|
||||||
|
|
||||||
// nsIDOMHTMLImageElement
|
// nsIDOMHTMLImageElement
|
||||||
NS_DECL_NSIDOMHTMLIMAGEELEMENT
|
NS_DECL_NSIDOMHTMLIMAGEELEMENT
|
||||||
|
@ -3222,7 +3222,7 @@ HTMLInputElement::Focus(ErrorResult& aError)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HTMLInputElement::IsInteractiveHTMLContent() const
|
HTMLInputElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const
|
||||||
{
|
{
|
||||||
return mType != NS_FORM_INPUT_HIDDEN;
|
return mType != NS_FORM_INPUT_HIDDEN;
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,7 @@ public:
|
|||||||
virtual void Focus(ErrorResult& aError) MOZ_OVERRIDE;
|
virtual void Focus(ErrorResult& aError) MOZ_OVERRIDE;
|
||||||
|
|
||||||
// Element
|
// Element
|
||||||
virtual bool IsInteractiveHTMLContent() const MOZ_OVERRIDE;
|
virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const MOZ_OVERRIDE;
|
||||||
|
|
||||||
// nsIDOMHTMLInputElement
|
// nsIDOMHTMLInputElement
|
||||||
NS_DECL_NSIDOMHTMLINPUTELEMENT
|
NS_DECL_NSIDOMHTMLINPUTELEMENT
|
||||||
|
@ -88,7 +88,7 @@ InInteractiveHTMLContent(nsIContent* aContent, nsIContent* aStop)
|
|||||||
nsIContent* content = aContent;
|
nsIContent* content = aContent;
|
||||||
while (content && content != aStop) {
|
while (content && content != aStop) {
|
||||||
if (content->IsElement() &&
|
if (content->IsElement() &&
|
||||||
content->AsElement()->IsInteractiveHTMLContent()) {
|
content->AsElement()->IsInteractiveHTMLContent(true)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
content = content->GetParent();
|
content = content->GetParent();
|
||||||
|
@ -33,7 +33,7 @@ public:
|
|||||||
NS_DECL_ISUPPORTS_INHERITED
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
|
||||||
// Element
|
// Element
|
||||||
virtual bool IsInteractiveHTMLContent() const MOZ_OVERRIDE
|
virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const MOZ_OVERRIDE
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ HTMLObjectElement::~HTMLObjectElement()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HTMLObjectElement::IsInteractiveHTMLContent() const
|
HTMLObjectElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const
|
||||||
{
|
{
|
||||||
return HasAttr(kNameSpaceID_None, nsGkAtoms::usemap);
|
return HasAttr(kNameSpaceID_None, nsGkAtoms::usemap);
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Element
|
// Element
|
||||||
virtual bool IsInteractiveHTMLContent() const MOZ_OVERRIDE;
|
virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const MOZ_OVERRIDE;
|
||||||
|
|
||||||
// nsIDOMHTMLObjectElement
|
// nsIDOMHTMLObjectElement
|
||||||
NS_DECL_NSIDOMHTMLOBJECTELEMENT
|
NS_DECL_NSIDOMHTMLOBJECTELEMENT
|
||||||
|
@ -148,7 +148,7 @@ public:
|
|||||||
virtual int32_t TabIndexDefault() MOZ_OVERRIDE;
|
virtual int32_t TabIndexDefault() MOZ_OVERRIDE;
|
||||||
|
|
||||||
// Element
|
// Element
|
||||||
virtual bool IsInteractiveHTMLContent() const MOZ_OVERRIDE
|
virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const MOZ_OVERRIDE
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ public:
|
|||||||
virtual int32_t TabIndexDefault() MOZ_OVERRIDE;
|
virtual int32_t TabIndexDefault() MOZ_OVERRIDE;
|
||||||
|
|
||||||
// Element
|
// Element
|
||||||
virtual bool IsInteractiveHTMLContent() const MOZ_OVERRIDE
|
virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const MOZ_OVERRIDE
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ nsresult HTMLVideoElement::SetAcceptHeader(nsIHttpChannel* aChannel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HTMLVideoElement::IsInteractiveHTMLContent() const
|
HTMLVideoElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const
|
||||||
{
|
{
|
||||||
return HasAttr(kNameSpaceID_None, nsGkAtoms::controls);
|
return HasAttr(kNameSpaceID_None, nsGkAtoms::controls);
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ public:
|
|||||||
virtual nsresult SetAcceptHeader(nsIHttpChannel* aChannel) MOZ_OVERRIDE;
|
virtual nsresult SetAcceptHeader(nsIHttpChannel* aChannel) MOZ_OVERRIDE;
|
||||||
|
|
||||||
// Element
|
// Element
|
||||||
virtual bool IsInteractiveHTMLContent() const MOZ_OVERRIDE;
|
virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const MOZ_OVERRIDE;
|
||||||
|
|
||||||
// WebIDL
|
// WebIDL
|
||||||
|
|
||||||
|
@ -1794,11 +1794,11 @@ nsGenericHTMLElement::IsLabelable() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
nsGenericHTMLElement::IsInteractiveHTMLContent() const
|
nsGenericHTMLElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const
|
||||||
{
|
{
|
||||||
return IsAnyOfHTMLElements(nsGkAtoms::details, nsGkAtoms::embed,
|
return IsAnyOfHTMLElements(nsGkAtoms::details, nsGkAtoms::embed,
|
||||||
nsGkAtoms::keygen) ||
|
nsGkAtoms::keygen) ||
|
||||||
HasAttr(kNameSpaceID_None, nsGkAtoms::tabindex);
|
(!aIgnoreTabindex && HasAttr(kNameSpaceID_None, nsGkAtoms::tabindex));
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<UndoManager>
|
already_AddRefed<UndoManager>
|
||||||
|
@ -923,7 +923,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual bool IsLabelable() const MOZ_OVERRIDE;
|
virtual bool IsLabelable() const MOZ_OVERRIDE;
|
||||||
virtual bool IsInteractiveHTMLContent() const MOZ_OVERRIDE;
|
virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const MOZ_OVERRIDE;
|
||||||
|
|
||||||
static bool TouchEventsEnabled(JSContext* /* unused */, JSObject* /* unused */);
|
static bool TouchEventsEnabled(JSContext* /* unused */, JSObject* /* unused */);
|
||||||
|
|
||||||
|
@ -32,13 +32,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=229925
|
|||||||
<select id="yes12"><option>select</option></select>
|
<select id="yes12"><option>select</option></select>
|
||||||
<textarea id="yes13" cols="1" rows="1"></textarea>
|
<textarea id="yes13" cols="1" rows="1"></textarea>
|
||||||
<video id="yes14" controls></video>
|
<video id="yes14" controls></video>
|
||||||
<span id="yes15" tabindex="1">tabindex</span>
|
|
||||||
|
|
||||||
<audio id="no1"></audio>
|
<audio id="no1"></audio>
|
||||||
<img id="no2" src="data:image/png,">
|
<img id="no2" src="data:image/png,">
|
||||||
<input id="no3" type="hidden">
|
<input id="no3" type="hidden">
|
||||||
<object id="no4">object</object>
|
<object id="no4">object</object>
|
||||||
<video id="no5"></video>
|
<video id="no5"></video>
|
||||||
|
<span id="no6" tabindex="1">tabindex</span>
|
||||||
</label>
|
</label>
|
||||||
</form>
|
</form>
|
||||||
<script class="testbody" type="text/javascript">
|
<script class="testbody" type="text/javascript">
|
||||||
@ -62,7 +62,6 @@ var yes_nodes = [
|
|||||||
document.getElementById("yes12"),
|
document.getElementById("yes12"),
|
||||||
document.getElementById("yes13"),
|
document.getElementById("yes13"),
|
||||||
document.getElementById("yes14"),
|
document.getElementById("yes14"),
|
||||||
document.getElementById("yes15"),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
var no_nodes = [
|
var no_nodes = [
|
||||||
@ -72,6 +71,7 @@ var no_nodes = [
|
|||||||
document.getElementById("no3"),
|
document.getElementById("no3"),
|
||||||
document.getElementById("no4"),
|
document.getElementById("no4"),
|
||||||
document.getElementById("no5"),
|
document.getElementById("no5"),
|
||||||
|
document.getElementById("no6"),
|
||||||
];
|
];
|
||||||
|
|
||||||
var target_clicked = false;
|
var target_clicked = false;
|
||||||
|
@ -233,6 +233,12 @@ ExtractH264CodecDetails(const nsAString& aCodec,
|
|||||||
aLevel = PromiseFlatString(Substring(aCodec, 9, 2)).ToInteger(&rv, 16);
|
aLevel = PromiseFlatString(Substring(aCodec, 9, 2)).ToInteger(&rv, 16);
|
||||||
NS_ENSURE_SUCCESS(rv, false);
|
NS_ENSURE_SUCCESS(rv, false);
|
||||||
|
|
||||||
|
if (aLevel == 9) {
|
||||||
|
aLevel = H264_LEVEL_1_b;
|
||||||
|
} else if (aLevel <= 5) {
|
||||||
|
aLevel *= 10;
|
||||||
|
}
|
||||||
|
|
||||||
// Capture the constraint_set flag value for the purpose of Telemetry.
|
// Capture the constraint_set flag value for the purpose of Telemetry.
|
||||||
// We don't NS_ENSURE_SUCCESS here because ExtractH264CodecDetails doesn't
|
// We don't NS_ENSURE_SUCCESS here because ExtractH264CodecDetails doesn't
|
||||||
// care about this, but we make sure constraints is above 4 (constraint_set5_flag)
|
// care about this, but we make sure constraints is above 4 (constraint_set5_flag)
|
||||||
|
@ -486,9 +486,7 @@ MP4Reader::ReadMetadata(MediaInfo* aInfo,
|
|||||||
mInfo.mVideo.mDisplay =
|
mInfo.mVideo.mDisplay =
|
||||||
nsIntSize(video.display_width, video.display_height);
|
nsIntSize(video.display_width, video.display_height);
|
||||||
mVideo.mCallback = new DecoderCallback(this, kVideo);
|
mVideo.mCallback = new DecoderCallback(this, kVideo);
|
||||||
if (!mIsEncrypted && mSharedDecoderManager) {
|
if (mSharedDecoderManager) {
|
||||||
// Note: Don't use SharedDecoderManager in EME content, as it doesn't
|
|
||||||
// handle reiniting the decoder properly yet.
|
|
||||||
mVideo.mDecoder =
|
mVideo.mDecoder =
|
||||||
mSharedDecoderManager->CreateVideoDecoder(mPlatform,
|
mSharedDecoderManager->CreateVideoDecoder(mPlatform,
|
||||||
video,
|
video,
|
||||||
@ -580,7 +578,7 @@ MP4Reader::GetNextKeyframeTime()
|
|||||||
void
|
void
|
||||||
MP4Reader::DisableHardwareAcceleration()
|
MP4Reader::DisableHardwareAcceleration()
|
||||||
{
|
{
|
||||||
if (HasVideo() && !mIsEncrypted && mSharedDecoderManager) {
|
if (HasVideo() && mSharedDecoderManager) {
|
||||||
mPlatform->DisableHardwareAcceleration();
|
mPlatform->DisableHardwareAcceleration();
|
||||||
|
|
||||||
const VideoDecoderConfig& video = mDemuxer->VideoConfig();
|
const VideoDecoderConfig& video = mDemuxer->VideoConfig();
|
||||||
@ -1111,9 +1109,7 @@ void MP4Reader::NotifyResourcesStatusChanged()
|
|||||||
void
|
void
|
||||||
MP4Reader::SetIdle()
|
MP4Reader::SetIdle()
|
||||||
{
|
{
|
||||||
if (!mIsEncrypted && mSharedDecoderManager && mVideo.mDecoder) {
|
if (mSharedDecoderManager && mVideo.mDecoder) {
|
||||||
// Note: Don't use SharedDecoderManager in EME content, as it doesn't
|
|
||||||
// handle reiniting the decoder properly yet.
|
|
||||||
mSharedDecoderManager->SetIdle(mVideo.mDecoder);
|
mSharedDecoderManager->SetIdle(mVideo.mDecoder);
|
||||||
NotifyResourcesStatusChanged();
|
NotifyResourcesStatusChanged();
|
||||||
}
|
}
|
||||||
|
@ -233,11 +233,27 @@ MediaSource::AddSourceBuffer(const nsAString& aType, ErrorResult& aRv)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
mSourceBuffers->Append(sourceBuffer);
|
mSourceBuffers->Append(sourceBuffer);
|
||||||
mActiveSourceBuffers->Append(sourceBuffer);
|
|
||||||
MSE_DEBUG("sourceBuffer=%p", sourceBuffer.get());
|
MSE_DEBUG("sourceBuffer=%p", sourceBuffer.get());
|
||||||
return sourceBuffer.forget();
|
return sourceBuffer.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaSource::SourceBufferIsActive(SourceBuffer* aSourceBuffer)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
mActiveSourceBuffers->ClearSimple();
|
||||||
|
bool found = false;
|
||||||
|
for (uint32_t i = 0; i < mSourceBuffers->Length(); i++) {
|
||||||
|
SourceBuffer* sourceBuffer = mSourceBuffers->IndexedGetter(i, found);
|
||||||
|
MOZ_ALWAYS_TRUE(found);
|
||||||
|
if (sourceBuffer == aSourceBuffer) {
|
||||||
|
mActiveSourceBuffers->Append(aSourceBuffer);
|
||||||
|
} else if (sourceBuffer->IsActive()) {
|
||||||
|
mActiveSourceBuffers->AppendSimple(sourceBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MediaSource::RemoveSourceBuffer(SourceBuffer& aSourceBuffer, ErrorResult& aRv)
|
MediaSource::RemoveSourceBuffer(SourceBuffer& aSourceBuffer, ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
|
@ -122,7 +122,7 @@ private:
|
|||||||
// MediaSourceDecoder uses DurationChange to set the duration
|
// MediaSourceDecoder uses DurationChange to set the duration
|
||||||
// without hitting the checks in SetDuration.
|
// without hitting the checks in SetDuration.
|
||||||
friend class mozilla::MediaSourceDecoder;
|
friend class mozilla::MediaSourceDecoder;
|
||||||
// SourceBuffer uses SetDuration
|
// SourceBuffer uses SetDuration and SourceBufferIsActive
|
||||||
friend class mozilla::dom::SourceBuffer;
|
friend class mozilla::dom::SourceBuffer;
|
||||||
|
|
||||||
~MediaSource();
|
~MediaSource();
|
||||||
@ -140,6 +140,9 @@ private:
|
|||||||
// SetDuration with no checks.
|
// SetDuration with no checks.
|
||||||
void SetDuration(double aDuration, MSRangeRemovalAction aAction);
|
void SetDuration(double aDuration, MSRangeRemovalAction aAction);
|
||||||
|
|
||||||
|
// Mark SourceBuffer as active and rebuild ActiveSourceBuffers.
|
||||||
|
void SourceBufferIsActive(SourceBuffer* aSourceBuffer);
|
||||||
|
|
||||||
nsRefPtr<SourceBufferList> mSourceBuffers;
|
nsRefPtr<SourceBufferList> mSourceBuffers;
|
||||||
nsRefPtr<SourceBufferList> mActiveSourceBuffers;
|
nsRefPtr<SourceBufferList> mActiveSourceBuffers;
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ MediaSourceReader::RequestAudioData()
|
|||||||
MOZ_DIAGNOSTIC_ASSERT(mSeekPromise.IsEmpty(), "No sample requests allowed while seeking");
|
MOZ_DIAGNOSTIC_ASSERT(mSeekPromise.IsEmpty(), "No sample requests allowed while seeking");
|
||||||
MOZ_DIAGNOSTIC_ASSERT(mAudioPromise.IsEmpty(), "No duplicate sample requests");
|
MOZ_DIAGNOSTIC_ASSERT(mAudioPromise.IsEmpty(), "No duplicate sample requests");
|
||||||
nsRefPtr<AudioDataPromise> p = mAudioPromise.Ensure(__func__);
|
nsRefPtr<AudioDataPromise> p = mAudioPromise.Ensure(__func__);
|
||||||
MSE_DEBUGV("");
|
MSE_DEBUGV("mLastAudioTime=%lld", mLastAudioTime);
|
||||||
if (!mAudioTrack) {
|
if (!mAudioTrack) {
|
||||||
MSE_DEBUG("called with no audio track");
|
MSE_DEBUG("called with no audio track");
|
||||||
mAudioPromise.Reject(DECODE_ERROR, __func__);
|
mAudioPromise.Reject(DECODE_ERROR, __func__);
|
||||||
@ -236,20 +236,21 @@ MediaSourceReader::OnAudioNotDecoded(NotDecodedReason aReason)
|
|||||||
mAudioRequest.Complete();
|
mAudioRequest.Complete();
|
||||||
|
|
||||||
MSE_DEBUG("aReason=%u IsEnded: %d", aReason, IsEnded());
|
MSE_DEBUG("aReason=%u IsEnded: %d", aReason, IsEnded());
|
||||||
if (aReason == DECODE_ERROR || aReason == CANCELED) {
|
if (aReason == CANCELED) {
|
||||||
mAudioPromise.Reject(aReason, __func__);
|
mAudioPromise.Reject(CANCELED, __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// End of stream. Force switching past this stream to another reader by
|
// If End of stream. Force switching past this stream to another reader by
|
||||||
// switching to the end of the buffered range.
|
// switching to the end of the buffered range.
|
||||||
MOZ_ASSERT(aReason == END_OF_STREAM);
|
int64_t lastAudioTime = mLastAudioTime;
|
||||||
if (mAudioSourceDecoder) {
|
if (aReason == END_OF_STREAM && mAudioSourceDecoder) {
|
||||||
AdjustEndTime(&mLastAudioTime, mAudioSourceDecoder);
|
AdjustEndTime(&mLastAudioTime, mAudioSourceDecoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SwitchSourceResult result = SwitchAudioSource(&mLastAudioTime);
|
||||||
// See if we can find a different source that can pick up where we left off.
|
// See if we can find a different source that can pick up where we left off.
|
||||||
if (SwitchAudioSource(&mLastAudioTime) == SOURCE_NEW) {
|
if (result == SOURCE_NEW) {
|
||||||
GetAudioReader()->ResetDecode();
|
GetAudioReader()->ResetDecode();
|
||||||
mAudioSeekRequest.Begin(GetAudioReader()->Seek(GetReaderAudioTime(mLastAudioTime), 0)
|
mAudioSeekRequest.Begin(GetAudioReader()->Seek(GetReaderAudioTime(mLastAudioTime), 0)
|
||||||
->RefableThen(GetTaskQueue(), __func__, this,
|
->RefableThen(GetTaskQueue(), __func__, this,
|
||||||
@ -258,7 +259,22 @@ MediaSourceReader::OnAudioNotDecoded(NotDecodedReason aReason)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we got a DECODE_ERROR and we have buffered data in the requested range
|
||||||
|
// then it must be a genuine decoding error.
|
||||||
|
// Otherwise we can assume that the data was either evicted or explicitely
|
||||||
|
// removed from the source buffer and we should wait for new data.
|
||||||
|
if (aReason == DECODE_ERROR && result != SOURCE_NONE) {
|
||||||
|
mAudioPromise.Reject(DECODE_ERROR, __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
CheckForWaitOrEndOfStream(MediaData::AUDIO_DATA, mLastAudioTime);
|
CheckForWaitOrEndOfStream(MediaData::AUDIO_DATA, mLastAudioTime);
|
||||||
|
|
||||||
|
if (mLastAudioTime - lastAudioTime >= EOS_FUZZ_US) {
|
||||||
|
// No decoders are available to switch to. We will re-attempt from the last
|
||||||
|
// failing position.
|
||||||
|
mLastAudioTime = lastAudioTime;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<MediaDecoderReader::VideoDataPromise>
|
nsRefPtr<MediaDecoderReader::VideoDataPromise>
|
||||||
@ -268,8 +284,8 @@ MediaSourceReader::RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThres
|
|||||||
MOZ_DIAGNOSTIC_ASSERT(mSeekPromise.IsEmpty(), "No sample requests allowed while seeking");
|
MOZ_DIAGNOSTIC_ASSERT(mSeekPromise.IsEmpty(), "No sample requests allowed while seeking");
|
||||||
MOZ_DIAGNOSTIC_ASSERT(mVideoPromise.IsEmpty(), "No duplicate sample requests");
|
MOZ_DIAGNOSTIC_ASSERT(mVideoPromise.IsEmpty(), "No duplicate sample requests");
|
||||||
nsRefPtr<VideoDataPromise> p = mVideoPromise.Ensure(__func__);
|
nsRefPtr<VideoDataPromise> p = mVideoPromise.Ensure(__func__);
|
||||||
MSE_DEBUGV("RequestVideoData(%d, %lld)",
|
MSE_DEBUGV("RequestVideoData(%d, %lld), mLastVideoTime=%lld",
|
||||||
aSkipToNextKeyframe, aTimeThreshold);
|
aSkipToNextKeyframe, aTimeThreshold, mLastVideoTime);
|
||||||
if (!mVideoTrack) {
|
if (!mVideoTrack) {
|
||||||
MSE_DEBUG("called with no video track");
|
MSE_DEBUG("called with no video track");
|
||||||
mVideoPromise.Reject(DECODE_ERROR, __func__);
|
mVideoPromise.Reject(DECODE_ERROR, __func__);
|
||||||
@ -367,20 +383,22 @@ MediaSourceReader::OnVideoNotDecoded(NotDecodedReason aReason)
|
|||||||
mVideoRequest.Complete();
|
mVideoRequest.Complete();
|
||||||
|
|
||||||
MSE_DEBUG("aReason=%u IsEnded: %d", aReason, IsEnded());
|
MSE_DEBUG("aReason=%u IsEnded: %d", aReason, IsEnded());
|
||||||
if (aReason == DECODE_ERROR || aReason == CANCELED) {
|
|
||||||
mVideoPromise.Reject(aReason, __func__);
|
if (aReason == CANCELED) {
|
||||||
|
mVideoPromise.Reject(CANCELED, __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// End of stream. Force switching past this stream to another reader by
|
// if End of stream. Force switching past this stream to another reader by
|
||||||
// switching to the end of the buffered range.
|
// switching to the end of the buffered range.
|
||||||
MOZ_ASSERT(aReason == END_OF_STREAM);
|
int64_t lastVideoTime = mLastVideoTime;
|
||||||
if (mVideoSourceDecoder) {
|
if (aReason == END_OF_STREAM && mVideoSourceDecoder) {
|
||||||
AdjustEndTime(&mLastVideoTime, mVideoSourceDecoder);
|
AdjustEndTime(&mLastVideoTime, mVideoSourceDecoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
// See if we can find a different reader that can pick up where we left off.
|
// See if we can find a different reader that can pick up where we left off.
|
||||||
if (SwitchVideoSource(&mLastVideoTime) == SOURCE_NEW) {
|
SwitchSourceResult result = SwitchVideoSource(&mLastVideoTime);
|
||||||
|
if (result == SOURCE_NEW) {
|
||||||
GetVideoReader()->ResetDecode();
|
GetVideoReader()->ResetDecode();
|
||||||
mVideoSeekRequest.Begin(GetVideoReader()->Seek(GetReaderVideoTime(mLastVideoTime), 0)
|
mVideoSeekRequest.Begin(GetVideoReader()->Seek(GetReaderVideoTime(mLastVideoTime), 0)
|
||||||
->RefableThen(GetTaskQueue(), __func__, this,
|
->RefableThen(GetTaskQueue(), __func__, this,
|
||||||
@ -389,7 +407,22 @@ MediaSourceReader::OnVideoNotDecoded(NotDecodedReason aReason)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we got a DECODE_ERROR and we have buffered data in the requested range
|
||||||
|
// then it must be a genuine decoding error.
|
||||||
|
// Otherwise we can assume that the data was either evicted or explicitely
|
||||||
|
// removed from the source buffer and we should wait for new data.
|
||||||
|
if (aReason == DECODE_ERROR && result != SOURCE_NONE) {
|
||||||
|
mVideoPromise.Reject(DECODE_ERROR, __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
CheckForWaitOrEndOfStream(MediaData::VIDEO_DATA, mLastVideoTime);
|
CheckForWaitOrEndOfStream(MediaData::VIDEO_DATA, mLastVideoTime);
|
||||||
|
|
||||||
|
if (mLastVideoTime - lastVideoTime >= EOS_FUZZ_US) {
|
||||||
|
// No decoders are available to switch to. We will re-attempt from the last
|
||||||
|
// failing position.
|
||||||
|
mLastVideoTime = lastVideoTime;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -322,6 +322,7 @@ SourceBuffer::SourceBuffer(MediaSource* aMediaSource, const nsACString& aType)
|
|||||||
, mTimestampOffset(0)
|
, mTimestampOffset(0)
|
||||||
, mAppendMode(SourceBufferAppendMode::Segments)
|
, mAppendMode(SourceBufferAppendMode::Segments)
|
||||||
, mUpdating(false)
|
, mUpdating(false)
|
||||||
|
, mActive(false)
|
||||||
, mUpdateID(0)
|
, mUpdateID(0)
|
||||||
, mType(aType)
|
, mType(aType)
|
||||||
{
|
{
|
||||||
@ -475,7 +476,11 @@ SourceBuffer::AppendDataCompletedWithSuccess(bool aGotMedia)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mTrackBuffer->HasInitSegment()) {
|
if (mTrackBuffer->HasInitSegment()) {
|
||||||
mMediaSource->QueueInitializationEvent();
|
if (!mActive) {
|
||||||
|
mActive = true;
|
||||||
|
mMediaSource->SourceBufferIsActive(this);
|
||||||
|
mMediaSource->QueueInitializationEvent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aGotMedia) {
|
if (aGotMedia) {
|
||||||
|
@ -117,6 +117,11 @@ public:
|
|||||||
// Actually remove data between aStart and aEnd
|
// Actually remove data between aStart and aEnd
|
||||||
void DoRangeRemoval(double aStart, double aEnd);
|
void DoRangeRemoval(double aStart, double aEnd);
|
||||||
|
|
||||||
|
bool IsActive() const
|
||||||
|
{
|
||||||
|
return mActive;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
void Dump(const char* aPath);
|
void Dump(const char* aPath);
|
||||||
#endif
|
#endif
|
||||||
@ -174,6 +179,8 @@ private:
|
|||||||
SourceBufferAppendMode mAppendMode;
|
SourceBufferAppendMode mAppendMode;
|
||||||
bool mUpdating;
|
bool mUpdating;
|
||||||
|
|
||||||
|
bool mActive;
|
||||||
|
|
||||||
// Each time mUpdating is set to true, mUpdateID will be incremented.
|
// Each time mUpdating is set to true, mUpdateID will be incremented.
|
||||||
// This allows for a queued AppendData task to identify if it was earlier
|
// This allows for a queued AppendData task to identify if it was earlier
|
||||||
// aborted and another AppendData queued.
|
// aborted and another AppendData queued.
|
||||||
|
@ -61,6 +61,13 @@ SourceBufferList::Append(SourceBuffer* aSourceBuffer)
|
|||||||
QueueAsyncSimpleEvent("addsourcebuffer");
|
QueueAsyncSimpleEvent("addsourcebuffer");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SourceBufferList::AppendSimple(SourceBuffer* aSourceBuffer)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
mSourceBuffers.AppendElement(aSourceBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SourceBufferList::Remove(SourceBuffer* aSourceBuffer)
|
SourceBufferList::Remove(SourceBuffer* aSourceBuffer)
|
||||||
{
|
{
|
||||||
@ -88,6 +95,13 @@ SourceBufferList::Clear()
|
|||||||
QueueAsyncSimpleEvent("removesourcebuffer");
|
QueueAsyncSimpleEvent("removesourcebuffer");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SourceBufferList::ClearSimple()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
mSourceBuffers.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
SourceBufferList::IsEmpty()
|
SourceBufferList::IsEmpty()
|
||||||
{
|
{
|
||||||
|
@ -78,6 +78,13 @@ public:
|
|||||||
// Returns the highest end time of any of the Sourcebuffers.
|
// Returns the highest end time of any of the Sourcebuffers.
|
||||||
double GetHighestBufferedEndTime();
|
double GetHighestBufferedEndTime();
|
||||||
|
|
||||||
|
// Append a SourceBuffer to the list. No event is fired.
|
||||||
|
void AppendSimple(SourceBuffer* aSourceBuffer);
|
||||||
|
|
||||||
|
// Remove all SourceBuffers from mSourceBuffers.
|
||||||
|
// No event is fired and no action is performed on the sourcebuffers.
|
||||||
|
void ClearSimple();
|
||||||
|
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
void Dump(const char* aPath);
|
void Dump(const char* aPath);
|
||||||
#endif
|
#endif
|
||||||
|
@ -47,7 +47,8 @@ runWithMSE(function () {
|
|||||||
ok(sb, "Create a SourceBuffer");
|
ok(sb, "Create a SourceBuffer");
|
||||||
is(ms.sourceBuffers.length, 1, "MediaSource.sourceBuffers is expected length");
|
is(ms.sourceBuffers.length, 1, "MediaSource.sourceBuffers is expected length");
|
||||||
is(ms.sourceBuffers[0], sb, "SourceBuffer in list matches our SourceBuffer");
|
is(ms.sourceBuffers[0], sb, "SourceBuffer in list matches our SourceBuffer");
|
||||||
is(ms.activeSourceBuffers[0], sb, "SourceBuffer in active list matches our SourceBuffer");
|
is(ms.activeSourceBuffers.length, 0, "MediaSource.activeSourceBuffers is expected length");
|
||||||
|
|
||||||
|
|
||||||
fetchWithXHR("seek.webm", function (arrayBuffer) {
|
fetchWithXHR("seek.webm", function (arrayBuffer) {
|
||||||
sb.appendBuffer(new Uint8Array(arrayBuffer));
|
sb.appendBuffer(new Uint8Array(arrayBuffer));
|
||||||
@ -70,6 +71,7 @@ runWithMSE(function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
sb.addEventListener("updateend", function () {
|
sb.addEventListener("updateend", function () {
|
||||||
|
is(ms.activeSourceBuffers[0], sb, "SourceBuffer in active list matches our SourceBuffer");
|
||||||
is(sb.updating, false, "SourceBuffer.updating is expected value in updateend event");
|
is(sb.updating, false, "SourceBuffer.updating is expected value in updateend event");
|
||||||
updateendCount++;
|
updateendCount++;
|
||||||
v.play();
|
v.play();
|
||||||
|
@ -580,8 +580,9 @@ NS_IMETHODIMP nsPluginInstanceOwner::ShowStatus(const char16_t *aStatusMsg)
|
|||||||
|
|
||||||
NS_IMETHODIMP nsPluginInstanceOwner::GetDocument(nsIDocument* *aDocument)
|
NS_IMETHODIMP nsPluginInstanceOwner::GetDocument(nsIDocument* *aDocument)
|
||||||
{
|
{
|
||||||
if (!aDocument)
|
if (!aDocument || !mContent) {
|
||||||
return NS_ERROR_NULL_POINTER;
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
// XXX sXBL/XBL2 issue: current doc or owner doc?
|
// XXX sXBL/XBL2 issue: current doc or owner doc?
|
||||||
// But keep in mind bug 322414 comment 33
|
// But keep in mind bug 322414 comment 33
|
||||||
|
@ -134,6 +134,60 @@ function testBlob() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This test is a copy of dom/html/test/formData_test.js testSend() modified to
|
||||||
|
// use the fetch API. Please change this if you change that.
|
||||||
|
function testFormDataSend() {
|
||||||
|
var file, blob = new Blob(['hey'], {type: 'text/plain'});
|
||||||
|
|
||||||
|
var fd = new FormData();
|
||||||
|
fd.append("string", "hey");
|
||||||
|
fd.append("empty", blob);
|
||||||
|
fd.append("explicit", blob, "explicit-file-name");
|
||||||
|
fd.append("explicit-empty", blob, "");
|
||||||
|
file = new File([blob], 'testname', {type: 'text/plain'});
|
||||||
|
fd.append("file-name", file);
|
||||||
|
file = new File([blob], '', {type: 'text/plain'});
|
||||||
|
fd.append("empty-file-name", file);
|
||||||
|
file = new File([blob], 'testname', {type: 'text/plain'});
|
||||||
|
fd.append("file-name-overwrite", file, "overwrite");
|
||||||
|
|
||||||
|
var req = new Request("/tests/dom/html/test/form_submit_server.sjs", {
|
||||||
|
method: 'POST',
|
||||||
|
body: fd,
|
||||||
|
});
|
||||||
|
|
||||||
|
return fetch(req).then((r) => {
|
||||||
|
ok(r.status, 200, "status should match");
|
||||||
|
return r.json().then((response) => {
|
||||||
|
for (var entry of response) {
|
||||||
|
if (entry.headers['Content-Disposition'] != 'form-data; name="string"') {
|
||||||
|
is(entry.headers['Content-Type'], 'text/plain');
|
||||||
|
}
|
||||||
|
|
||||||
|
is(entry.body, 'hey');
|
||||||
|
}
|
||||||
|
|
||||||
|
is(response[1].headers['Content-Disposition'],
|
||||||
|
'form-data; name="empty"; filename="blob"');
|
||||||
|
|
||||||
|
is(response[2].headers['Content-Disposition'],
|
||||||
|
'form-data; name="explicit"; filename="explicit-file-name"');
|
||||||
|
|
||||||
|
is(response[3].headers['Content-Disposition'],
|
||||||
|
'form-data; name="explicit-empty"; filename=""');
|
||||||
|
|
||||||
|
is(response[4].headers['Content-Disposition'],
|
||||||
|
'form-data; name="file-name"; filename="testname"');
|
||||||
|
|
||||||
|
is(response[5].headers['Content-Disposition'],
|
||||||
|
'form-data; name="empty-file-name"; filename=""');
|
||||||
|
|
||||||
|
is(response[6].headers['Content-Disposition'],
|
||||||
|
'form-data; name="file-name-overwrite"; filename="overwrite"');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function runTest() {
|
function runTest() {
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
.then(testURL)
|
.then(testURL)
|
||||||
@ -141,5 +195,6 @@ function runTest() {
|
|||||||
.then(testRequestGET)
|
.then(testRequestGET)
|
||||||
.then(testResponses)
|
.then(testResponses)
|
||||||
.then(testBlob)
|
.then(testBlob)
|
||||||
|
.then(testFormDataSend)
|
||||||
// Put more promise based tests here.
|
// Put more promise based tests here.
|
||||||
}
|
}
|
||||||
|
@ -46,9 +46,11 @@ var corsServerPath = "/tests/dom/base/test/file_CrossSiteXHR_server.sjs?";
|
|||||||
function testModeNoCors() {
|
function testModeNoCors() {
|
||||||
// Fetch spec, section 4, step 4, response tainting should be set opaque, so
|
// Fetch spec, section 4, step 4, response tainting should be set opaque, so
|
||||||
// that fetching leads to an opaque filtered response in step 8.
|
// that fetching leads to an opaque filtered response in step 8.
|
||||||
var r = new Request("http://example.com" + corsServerPath + "status=200&allowOrigin=*", { mode: "no-cors" });
|
var r = new Request("http://example.com" + corsServerPath + "status=200", { mode: "no-cors" });
|
||||||
return fetch(r).then(function(res) {
|
return fetch(r).then(function(res) {
|
||||||
ok(isOpaqueResponse(res), "no-cors Request fetch should result in opaque response");
|
ok(isOpaqueResponse(res), "no-cors Request fetch should result in opaque response");
|
||||||
|
}, function(e) {
|
||||||
|
ok(false, "no-cors Request fetch should not error");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1019,7 +1021,7 @@ function testRedirects() {
|
|||||||
hops: [{ server: "http://example.com",
|
hops: [{ server: "http://example.com",
|
||||||
allowOrigin: origin
|
allowOrigin: origin
|
||||||
},
|
},
|
||||||
{ server: "http://test2.mochi.test:8000",
|
{ server: "http://test2.mochi.test:8888",
|
||||||
allowOrigin: origin
|
allowOrigin: origin
|
||||||
},
|
},
|
||||||
{ server: "http://sub2.xn--lt-uia.mochi.test:8888",
|
{ server: "http://sub2.xn--lt-uia.mochi.test:8888",
|
||||||
@ -1035,7 +1037,7 @@ function testRedirects() {
|
|||||||
hops: [{ server: "http://example.com",
|
hops: [{ server: "http://example.com",
|
||||||
allowOrigin: origin
|
allowOrigin: origin
|
||||||
},
|
},
|
||||||
{ server: "http://test2.mochi.test:8000",
|
{ server: "http://test2.mochi.test:8888",
|
||||||
allowOrigin: origin
|
allowOrigin: origin
|
||||||
},
|
},
|
||||||
{ server: "http://sub2.xn--lt-uia.mochi.test:8888",
|
{ server: "http://sub2.xn--lt-uia.mochi.test:8888",
|
||||||
@ -1067,7 +1069,7 @@ function testRedirects() {
|
|||||||
hops: [{ server: "http://example.com",
|
hops: [{ server: "http://example.com",
|
||||||
allowOrigin: origin
|
allowOrigin: origin
|
||||||
},
|
},
|
||||||
{ server: "http://test2.mochi.test:8000",
|
{ server: "http://test2.mochi.test:8888",
|
||||||
allowOrigin: origin
|
allowOrigin: origin
|
||||||
},
|
},
|
||||||
{ server: "http://sub2.xn--lt-uia.mochi.test:8888",
|
{ server: "http://sub2.xn--lt-uia.mochi.test:8888",
|
||||||
@ -1083,7 +1085,7 @@ function testRedirects() {
|
|||||||
hops: [{ server: "http://example.com",
|
hops: [{ server: "http://example.com",
|
||||||
allowOrigin: origin
|
allowOrigin: origin
|
||||||
},
|
},
|
||||||
{ server: "http://test2.mochi.test:8000",
|
{ server: "http://test2.mochi.test:8888",
|
||||||
allowOrigin: origin
|
allowOrigin: origin
|
||||||
},
|
},
|
||||||
{ server: "http://sub2.xn--lt-uia.mochi.test:8888",
|
{ server: "http://sub2.xn--lt-uia.mochi.test:8888",
|
||||||
@ -1099,7 +1101,7 @@ function testRedirects() {
|
|||||||
hops: [{ server: "http://example.com",
|
hops: [{ server: "http://example.com",
|
||||||
allowOrigin: origin
|
allowOrigin: origin
|
||||||
},
|
},
|
||||||
{ server: "http://test2.mochi.test:8000",
|
{ server: "http://test2.mochi.test:8888",
|
||||||
allowOrigin: origin
|
allowOrigin: origin
|
||||||
},
|
},
|
||||||
{ server: "http://sub2.xn--lt-uia.mochi.test:8888",
|
{ server: "http://sub2.xn--lt-uia.mochi.test:8888",
|
||||||
|
@ -8,9 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
typedef object JSON;
|
typedef object JSON;
|
||||||
// FIXME(nsm): Bug 739173: FormData is not available in workers.
|
typedef (ArrayBuffer or ArrayBufferView or Blob or FormData or USVString or URLSearchParams) BodyInit;
|
||||||
// typedef (ArrayBuffer or ArrayBufferView or Blob or FormData or USVString or URLSearchParams) BodyInit;
|
|
||||||
typedef (ArrayBuffer or ArrayBufferView or Blob or USVString or URLSearchParams) BodyInit;
|
|
||||||
|
|
||||||
[NoInterfaceObject, Exposed=(Window,Worker)]
|
[NoInterfaceObject, Exposed=(Window,Worker)]
|
||||||
interface Body {
|
interface Body {
|
||||||
|
@ -1135,22 +1135,8 @@ CompositorParent::ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
|
|||||||
// When testing we synchronously update the shadow tree with the animated
|
// When testing we synchronously update the shadow tree with the animated
|
||||||
// values to avoid race conditions when calling GetAnimationTransform etc.
|
// values to avoid race conditions when calling GetAnimationTransform etc.
|
||||||
// (since the above SetShadowProperties will remove animation effects).
|
// (since the above SetShadowProperties will remove animation effects).
|
||||||
// However, we only do this update when a composite operation is already
|
if (mIsTesting) {
|
||||||
// scheduled in order to better match the behavior under regular sampling
|
ApplyAsyncProperties(aLayerTree);
|
||||||
// conditions.
|
|
||||||
bool needTestComposite = mIsTesting && root &&
|
|
||||||
(mCurrentCompositeTask ||
|
|
||||||
(mCompositorVsyncObserver &&
|
|
||||||
mCompositorVsyncObserver->NeedsComposite()));
|
|
||||||
if (needTestComposite) {
|
|
||||||
AutoResolveRefLayers resolve(mCompositionManager);
|
|
||||||
bool requestNextFrame =
|
|
||||||
mCompositionManager->TransformShadowTree(mTestTime);
|
|
||||||
if (!requestNextFrame) {
|
|
||||||
CancelCurrentCompositeTask();
|
|
||||||
// Pretend we composited in case someone is waiting for this event.
|
|
||||||
DidComposite();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mLayerManager->NotifyShadowTreeTransaction();
|
mLayerManager->NotifyShadowTreeTransaction();
|
||||||
@ -1197,6 +1183,31 @@ CompositorParent::LeaveTestMode(LayerTransactionParent* aLayerTree)
|
|||||||
mIsTesting = false;
|
mIsTesting = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CompositorParent::ApplyAsyncProperties(LayerTransactionParent* aLayerTree)
|
||||||
|
{
|
||||||
|
// NOTE: This should only be used for testing. For example, when mIsTesting is
|
||||||
|
// true or when called from test-only methods like
|
||||||
|
// LayerTransactionParent::RecvGetAnimationTransform.
|
||||||
|
|
||||||
|
// Synchronously update the layer tree, but only if a composite was already
|
||||||
|
// scehduled.
|
||||||
|
if (aLayerTree->GetRoot() &&
|
||||||
|
(mCurrentCompositeTask ||
|
||||||
|
(mCompositorVsyncObserver &&
|
||||||
|
mCompositorVsyncObserver->NeedsComposite()))) {
|
||||||
|
AutoResolveRefLayers resolve(mCompositionManager);
|
||||||
|
TimeStamp time = mIsTesting ? mTestTime : mLastCompose;
|
||||||
|
bool requestNextFrame =
|
||||||
|
mCompositionManager->TransformShadowTree(time);
|
||||||
|
if (!requestNextFrame) {
|
||||||
|
CancelCurrentCompositeTask();
|
||||||
|
// Pretend we composited in case someone is waiting for this event.
|
||||||
|
DidComposite();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CompositorParent::RecvRequestOverfill()
|
CompositorParent::RecvRequestOverfill()
|
||||||
{
|
{
|
||||||
|
@ -194,6 +194,8 @@ public:
|
|||||||
virtual bool SetTestSampleTime(LayerTransactionParent* aLayerTree,
|
virtual bool SetTestSampleTime(LayerTransactionParent* aLayerTree,
|
||||||
const TimeStamp& aTime) MOZ_OVERRIDE;
|
const TimeStamp& aTime) MOZ_OVERRIDE;
|
||||||
virtual void LeaveTestMode(LayerTransactionParent* aLayerTree) MOZ_OVERRIDE;
|
virtual void LeaveTestMode(LayerTransactionParent* aLayerTree) MOZ_OVERRIDE;
|
||||||
|
virtual void ApplyAsyncProperties(LayerTransactionParent* aLayerTree)
|
||||||
|
MOZ_OVERRIDE;
|
||||||
virtual void GetAPZTestData(const LayerTransactionParent* aLayerTree,
|
virtual void GetAPZTestData(const LayerTransactionParent* aLayerTree,
|
||||||
APZTestData* aOutData) MOZ_OVERRIDE;
|
APZTestData* aOutData) MOZ_OVERRIDE;
|
||||||
virtual AsyncCompositionManager* GetCompositionManager(LayerTransactionParent* aLayerTree) MOZ_OVERRIDE { return mCompositionManager; }
|
virtual AsyncCompositionManager* GetCompositionManager(LayerTransactionParent* aLayerTree) MOZ_OVERRIDE { return mCompositionManager; }
|
||||||
|
@ -682,6 +682,12 @@ LayerTransactionParent::RecvGetAnimationTransform(PLayerParent* aParent,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure we apply the latest animation style or else we can end up with
|
||||||
|
// a race between when we temporarily clear the animation transform (in
|
||||||
|
// CompositorParent::SetShadowProperties) and when animation recalculates
|
||||||
|
// the value.
|
||||||
|
mShadowLayersManager->ApplyAsyncProperties(this);
|
||||||
|
|
||||||
// This method is specific to transforms applied by animation.
|
// This method is specific to transforms applied by animation.
|
||||||
// This is because this method uses the information stored with an animation
|
// This is because this method uses the information stored with an animation
|
||||||
// such as the origin of the reference frame corresponding to the layer, to
|
// such as the origin of the reference frame corresponding to the layer, to
|
||||||
|
@ -35,6 +35,7 @@ public:
|
|||||||
virtual bool SetTestSampleTime(LayerTransactionParent* aLayerTree,
|
virtual bool SetTestSampleTime(LayerTransactionParent* aLayerTree,
|
||||||
const TimeStamp& aTime) { return true; }
|
const TimeStamp& aTime) { return true; }
|
||||||
virtual void LeaveTestMode(LayerTransactionParent* aLayerTree) { }
|
virtual void LeaveTestMode(LayerTransactionParent* aLayerTree) { }
|
||||||
|
virtual void ApplyAsyncProperties(LayerTransactionParent* aLayerTree) { }
|
||||||
virtual void GetAPZTestData(const LayerTransactionParent* aLayerTree,
|
virtual void GetAPZTestData(const LayerTransactionParent* aLayerTree,
|
||||||
APZTestData* aOutData) { }
|
APZTestData* aOutData) { }
|
||||||
};
|
};
|
||||||
|
@ -232,7 +232,7 @@ private:
|
|||||||
|
|
||||||
DECL_GFX_PREF(Once, "image.cache.timeweight", ImageCacheTimeWeight, int32_t, 500);
|
DECL_GFX_PREF(Once, "image.cache.timeweight", ImageCacheTimeWeight, int32_t, 500);
|
||||||
DECL_GFX_PREF(Once, "image.cache.size", ImageCacheSize, int32_t, 5*1024*1024);
|
DECL_GFX_PREF(Once, "image.cache.size", ImageCacheSize, int32_t, 5*1024*1024);
|
||||||
DECL_GFX_PREF(Live, "image.downscale-during-decode.enabled", ImageDownscaleDuringDecodeEnabled, bool, false);
|
DECL_GFX_PREF(Live, "image.downscale-during-decode.enabled", ImageDownscaleDuringDecodeEnabled, bool, true);
|
||||||
DECL_GFX_PREF(Live, "image.high_quality_downscaling.enabled", ImageHQDownscalingEnabled, bool, false);
|
DECL_GFX_PREF(Live, "image.high_quality_downscaling.enabled", ImageHQDownscalingEnabled, bool, false);
|
||||||
DECL_GFX_PREF(Live, "image.high_quality_downscaling.min_factor", ImageHQDownscalingMinFactor, uint32_t, 1000);
|
DECL_GFX_PREF(Live, "image.high_quality_downscaling.min_factor", ImageHQDownscalingMinFactor, uint32_t, 1000);
|
||||||
DECL_GFX_PREF(Live, "image.high_quality_upscaling.max_size", ImageHQUpscalingMaxSize, uint32_t, 20971520);
|
DECL_GFX_PREF(Live, "image.high_quality_upscaling.max_size", ImageHQUpscalingMaxSize, uint32_t, 20971520);
|
||||||
|
@ -98,7 +98,7 @@ native nsIntRectByVal(nsIntRect);
|
|||||||
[ref] native nsIntSize(nsIntSize);
|
[ref] native nsIntSize(nsIntSize);
|
||||||
native nsSize(nsSize);
|
native nsSize(nsSize);
|
||||||
[ptr] native nsIFrame(nsIFrame);
|
[ptr] native nsIFrame(nsIFrame);
|
||||||
[ptr] native ImageContainer(mozilla::layers::ImageContainer);
|
native TempRefImageContainer(already_AddRefed<mozilla::layers::ImageContainer>);
|
||||||
[ref] native ImageRegion(mozilla::image::ImageRegion);
|
[ref] native ImageRegion(mozilla::image::ImageRegion);
|
||||||
[ptr] native LayerManager(mozilla::layers::LayerManager);
|
[ptr] native LayerManager(mozilla::layers::LayerManager);
|
||||||
native Orientation(mozilla::image::Orientation);
|
native Orientation(mozilla::image::Orientation);
|
||||||
@ -116,7 +116,7 @@ native nsIntSizeByVal(nsIntSize);
|
|||||||
*
|
*
|
||||||
* Internally, imgIContainer also manages animation of images.
|
* Internally, imgIContainer also manages animation of images.
|
||||||
*/
|
*/
|
||||||
[scriptable, builtinclass, uuid(9a43298b-bf49-44fc-9abe-9ff702f1bd25)]
|
[scriptable, builtinclass, uuid(44fbd7d5-e417-4d31-ae4a-8ad61d07eb3c)]
|
||||||
interface imgIContainer : nsISupports
|
interface imgIContainer : nsISupports
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -277,8 +277,17 @@ interface imgIContainer : nsISupports
|
|||||||
/**
|
/**
|
||||||
* Attempts to create an ImageContainer (and Image) containing the current
|
* Attempts to create an ImageContainer (and Image) containing the current
|
||||||
* frame. Only valid for RASTER type images.
|
* frame. Only valid for RASTER type images.
|
||||||
|
*
|
||||||
|
* @param aManager The LayerManager which will be used to create the
|
||||||
|
* ImageContainer.
|
||||||
|
* @param aFlags Decoding / drawing flags (in other words, FLAG_* flags).
|
||||||
|
* Currently only FLAG_SYNC_DECODE and FLAG_SYNC_DECODE_IF_FAST
|
||||||
|
* are supported.
|
||||||
|
* @return An ImageContainer for the current frame, or nullptr if one could
|
||||||
|
* not be created.
|
||||||
*/
|
*/
|
||||||
[noscript] ImageContainer getImageContainer(in LayerManager aManager);
|
[noscript, notxpcom] TempRefImageContainer getImageContainer(in LayerManager aManager,
|
||||||
|
in uint32_t aFlags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draw the requested frame of this image onto the context specified.
|
* Draw the requested frame of this image onto the context specified.
|
||||||
|
@ -266,8 +266,8 @@ ClippedImage::GetFrameInternal(const nsIntSize& aSize,
|
|||||||
return mCachedSurface->Surface();
|
return mCachedSurface->Surface();
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP_(already_AddRefed<ImageContainer>)
|
||||||
ClippedImage::GetImageContainer(LayerManager* aManager, ImageContainer** _retval)
|
ClippedImage::GetImageContainer(LayerManager* aManager, uint32_t aFlags)
|
||||||
{
|
{
|
||||||
// XXX(seth): We currently don't have a way of clipping the result of
|
// XXX(seth): We currently don't have a way of clipping the result of
|
||||||
// GetImageContainer. We work around this by always returning null, but if it
|
// GetImageContainer. We work around this by always returning null, but if it
|
||||||
@ -276,11 +276,10 @@ ClippedImage::GetImageContainer(LayerManager* aManager, ImageContainer** _retval
|
|||||||
// that method for performance reasons.
|
// that method for performance reasons.
|
||||||
|
|
||||||
if (!ShouldClip()) {
|
if (!ShouldClip()) {
|
||||||
return InnerImage()->GetImageContainer(aManager, _retval);
|
return InnerImage()->GetImageContainer(aManager, aFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
*_retval = nullptr;
|
return nullptr;
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -37,8 +37,9 @@ public:
|
|||||||
NS_IMETHOD GetIntrinsicRatio(nsSize* aRatio) MOZ_OVERRIDE;
|
NS_IMETHOD GetIntrinsicRatio(nsSize* aRatio) MOZ_OVERRIDE;
|
||||||
NS_IMETHOD_(TemporaryRef<SourceSurface>)
|
NS_IMETHOD_(TemporaryRef<SourceSurface>)
|
||||||
GetFrame(uint32_t aWhichFrame, uint32_t aFlags) MOZ_OVERRIDE;
|
GetFrame(uint32_t aWhichFrame, uint32_t aFlags) MOZ_OVERRIDE;
|
||||||
NS_IMETHOD GetImageContainer(layers::LayerManager* aManager,
|
NS_IMETHOD_(already_AddRefed<layers::ImageContainer>)
|
||||||
layers::ImageContainer** _retval) MOZ_OVERRIDE;
|
GetImageContainer(layers::LayerManager* aManager,
|
||||||
|
uint32_t aFlags) MOZ_OVERRIDE;
|
||||||
NS_IMETHOD_(DrawResult) Draw(gfxContext* aContext,
|
NS_IMETHOD_(DrawResult) Draw(gfxContext* aContext,
|
||||||
const nsIntSize& aSize,
|
const nsIntSize& aSize,
|
||||||
const ImageRegion& aRegion,
|
const ImageRegion& aRegion,
|
||||||
|
@ -205,12 +205,10 @@ DynamicImage::IsOpaque()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP_(already_AddRefed<ImageContainer>)
|
||||||
DynamicImage::GetImageContainer(LayerManager* aManager,
|
DynamicImage::GetImageContainer(LayerManager* aManager, uint32_t aFlags)
|
||||||
ImageContainer** _retval)
|
|
||||||
{
|
{
|
||||||
*_retval = nullptr;
|
return nullptr;
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP_(DrawResult)
|
NS_IMETHODIMP_(DrawResult)
|
||||||
|
@ -44,18 +44,15 @@ FrozenImage::GetFrame(uint32_t aWhichFrame,
|
|||||||
return InnerImage()->GetFrame(FRAME_FIRST, aFlags);
|
return InnerImage()->GetFrame(FRAME_FIRST, aFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP_(already_AddRefed<ImageContainer>)
|
||||||
FrozenImage::GetImageContainer(layers::LayerManager* aManager,
|
FrozenImage::GetImageContainer(layers::LayerManager* aManager, uint32_t aFlags)
|
||||||
layers::ImageContainer** _retval)
|
|
||||||
{
|
{
|
||||||
// XXX(seth): GetImageContainer does not currently support anything but the
|
// XXX(seth): GetImageContainer does not currently support anything but the
|
||||||
// current frame. We work around this by always returning null, but if it ever
|
// current frame. We work around this by always returning null, but if it ever
|
||||||
// turns out that FrozenImage is widely used on codepaths that can actually
|
// turns out that FrozenImage is widely used on codepaths that can actually
|
||||||
// benefit from GetImageContainer, it would be a good idea to fix that method
|
// benefit from GetImageContainer, it would be a good idea to fix that method
|
||||||
// for performance reasons.
|
// for performance reasons.
|
||||||
|
return nullptr;
|
||||||
*_retval = nullptr;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP_(DrawResult)
|
NS_IMETHODIMP_(DrawResult)
|
||||||
|
@ -37,8 +37,9 @@ public:
|
|||||||
NS_IMETHOD GetAnimated(bool* aAnimated) MOZ_OVERRIDE;
|
NS_IMETHOD GetAnimated(bool* aAnimated) MOZ_OVERRIDE;
|
||||||
NS_IMETHOD_(TemporaryRef<SourceSurface>)
|
NS_IMETHOD_(TemporaryRef<SourceSurface>)
|
||||||
GetFrame(uint32_t aWhichFrame, uint32_t aFlags) MOZ_OVERRIDE;
|
GetFrame(uint32_t aWhichFrame, uint32_t aFlags) MOZ_OVERRIDE;
|
||||||
NS_IMETHOD GetImageContainer(layers::LayerManager* aManager,
|
NS_IMETHOD_(already_AddRefed<layers::ImageContainer>)
|
||||||
layers::ImageContainer** _retval) MOZ_OVERRIDE;
|
GetImageContainer(layers::LayerManager* aManager,
|
||||||
|
uint32_t aFlags) MOZ_OVERRIDE;
|
||||||
NS_IMETHOD_(DrawResult) Draw(gfxContext* aContext,
|
NS_IMETHOD_(DrawResult) Draw(gfxContext* aContext,
|
||||||
const nsIntSize& aSize,
|
const nsIntSize& aSize,
|
||||||
const ImageRegion& aRegion,
|
const ImageRegion& aRegion,
|
||||||
|
@ -192,11 +192,10 @@ ImageWrapper::IsOpaque()
|
|||||||
return mInnerImage->IsOpaque();
|
return mInnerImage->IsOpaque();
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP_(already_AddRefed<ImageContainer>)
|
||||||
ImageWrapper::GetImageContainer(LayerManager* aManager,
|
ImageWrapper::GetImageContainer(LayerManager* aManager, uint32_t aFlags)
|
||||||
ImageContainer** _retval)
|
|
||||||
{
|
{
|
||||||
return mInnerImage->GetImageContainer(aManager, _retval);
|
return mInnerImage->GetImageContainer(aManager, aFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP_(DrawResult)
|
NS_IMETHODIMP_(DrawResult)
|
||||||
|
@ -122,9 +122,8 @@ OrientedImage::GetFrame(uint32_t aWhichFrame,
|
|||||||
return target->Snapshot();
|
return target->Snapshot();
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP_(already_AddRefed<ImageContainer>)
|
||||||
OrientedImage::GetImageContainer(LayerManager* aManager,
|
OrientedImage::GetImageContainer(LayerManager* aManager, uint32_t aFlags)
|
||||||
ImageContainer** _retval)
|
|
||||||
{
|
{
|
||||||
// XXX(seth): We currently don't have a way of orienting the result of
|
// XXX(seth): We currently don't have a way of orienting the result of
|
||||||
// GetImageContainer. We work around this by always returning null, but if it
|
// GetImageContainer. We work around this by always returning null, but if it
|
||||||
@ -133,11 +132,10 @@ OrientedImage::GetImageContainer(LayerManager* aManager,
|
|||||||
// that method for performance reasons.
|
// that method for performance reasons.
|
||||||
|
|
||||||
if (mOrientation.IsIdentity()) {
|
if (mOrientation.IsIdentity()) {
|
||||||
return InnerImage()->GetImageContainer(aManager, _retval);
|
return InnerImage()->GetImageContainer(aManager, aFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
*_retval = nullptr;
|
return nullptr;
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MatrixBuilder
|
struct MatrixBuilder
|
||||||
|
@ -34,8 +34,9 @@ public:
|
|||||||
NS_IMETHOD GetIntrinsicRatio(nsSize* aRatio) MOZ_OVERRIDE;
|
NS_IMETHOD GetIntrinsicRatio(nsSize* aRatio) MOZ_OVERRIDE;
|
||||||
NS_IMETHOD_(TemporaryRef<SourceSurface>)
|
NS_IMETHOD_(TemporaryRef<SourceSurface>)
|
||||||
GetFrame(uint32_t aWhichFrame, uint32_t aFlags) MOZ_OVERRIDE;
|
GetFrame(uint32_t aWhichFrame, uint32_t aFlags) MOZ_OVERRIDE;
|
||||||
NS_IMETHOD GetImageContainer(layers::LayerManager* aManager,
|
NS_IMETHOD_(already_AddRefed<layers::ImageContainer>)
|
||||||
layers::ImageContainer** _retval) MOZ_OVERRIDE;
|
GetImageContainer(layers::LayerManager* aManager,
|
||||||
|
uint32_t aFlags) MOZ_OVERRIDE;
|
||||||
NS_IMETHOD_(DrawResult) Draw(gfxContext* aContext,
|
NS_IMETHOD_(DrawResult) Draw(gfxContext* aContext,
|
||||||
const nsIntSize& aSize,
|
const nsIntSize& aSize,
|
||||||
const ImageRegion& aRegion,
|
const ImageRegion& aRegion,
|
||||||
|
@ -256,6 +256,7 @@ RasterImage::RasterImage(ProgressTracker* aProgressTracker,
|
|||||||
mLockCount(0),
|
mLockCount(0),
|
||||||
mDecodeCount(0),
|
mDecodeCount(0),
|
||||||
mRequestedSampleSize(0),
|
mRequestedSampleSize(0),
|
||||||
|
mLastImageContainerDrawResult(DrawResult::NOT_READY),
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
mFramesNotified(0),
|
mFramesNotified(0),
|
||||||
#endif
|
#endif
|
||||||
@ -325,6 +326,7 @@ RasterImage::Init(const char* aMimeType,
|
|||||||
|
|
||||||
// Lock this image's surfaces in the SurfaceCache if we're not discardable.
|
// Lock this image's surfaces in the SurfaceCache if we're not discardable.
|
||||||
if (!mDiscardable) {
|
if (!mDiscardable) {
|
||||||
|
mLockCount++;
|
||||||
SurfaceCache::LockImage(ImageKey(this));
|
SurfaceCache::LockImage(ImageKey(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -727,19 +729,21 @@ NS_IMETHODIMP_(TemporaryRef<SourceSurface>)
|
|||||||
RasterImage::GetFrame(uint32_t aWhichFrame,
|
RasterImage::GetFrame(uint32_t aWhichFrame,
|
||||||
uint32_t aFlags)
|
uint32_t aFlags)
|
||||||
{
|
{
|
||||||
return GetFrameInternal(aWhichFrame, aFlags);
|
return GetFrameInternal(aWhichFrame, aFlags).second().forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
TemporaryRef<SourceSurface>
|
Pair<DrawResult, RefPtr<SourceSurface>>
|
||||||
RasterImage::GetFrameInternal(uint32_t aWhichFrame, uint32_t aFlags)
|
RasterImage::GetFrameInternal(uint32_t aWhichFrame, uint32_t aFlags)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aWhichFrame <= FRAME_MAX_VALUE);
|
MOZ_ASSERT(aWhichFrame <= FRAME_MAX_VALUE);
|
||||||
|
|
||||||
if (aWhichFrame > FRAME_MAX_VALUE)
|
if (aWhichFrame > FRAME_MAX_VALUE) {
|
||||||
return nullptr;
|
return MakePair(DrawResult::BAD_ARGS, RefPtr<SourceSurface>());
|
||||||
|
}
|
||||||
|
|
||||||
if (mError)
|
if (mError) {
|
||||||
return nullptr;
|
return MakePair(DrawResult::BAD_IMAGE, RefPtr<SourceSurface>());
|
||||||
|
}
|
||||||
|
|
||||||
// Get the frame. If it's not there, it's probably the caller's fault for
|
// Get the frame. If it's not there, it's probably the caller's fault for
|
||||||
// not waiting for the data to be loaded from the network or not passing
|
// not waiting for the data to be loaded from the network or not passing
|
||||||
@ -748,7 +752,7 @@ RasterImage::GetFrameInternal(uint32_t aWhichFrame, uint32_t aFlags)
|
|||||||
LookupFrame(GetRequestedFrameIndex(aWhichFrame), mSize, aFlags);
|
LookupFrame(GetRequestedFrameIndex(aWhichFrame), mSize, aFlags);
|
||||||
if (!frameRef) {
|
if (!frameRef) {
|
||||||
// The OS threw this frame away and we couldn't redecode it.
|
// The OS threw this frame away and we couldn't redecode it.
|
||||||
return nullptr;
|
return MakePair(DrawResult::TEMPORARY_ERROR, RefPtr<SourceSurface>());
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this frame covers the entire image, we can just reuse its existing
|
// If this frame covers the entire image, we can just reuse its existing
|
||||||
@ -767,50 +771,57 @@ RasterImage::GetFrameInternal(uint32_t aWhichFrame, uint32_t aFlags)
|
|||||||
frameSurf = CopyFrame(aWhichFrame, aFlags);
|
frameSurf = CopyFrame(aWhichFrame, aFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
return frameSurf;
|
if (!frameRef->IsImageComplete()) {
|
||||||
|
return MakePair(DrawResult::INCOMPLETE, Move(frameSurf));
|
||||||
|
}
|
||||||
|
|
||||||
|
return MakePair(DrawResult::SUCCESS, Move(frameSurf));
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<layers::Image>
|
Pair<DrawResult, nsRefPtr<layers::Image>>
|
||||||
RasterImage::GetCurrentImage(ImageContainer* aContainer)
|
RasterImage::GetCurrentImage(ImageContainer* aContainer, uint32_t aFlags)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
MOZ_ASSERT(aContainer);
|
MOZ_ASSERT(aContainer);
|
||||||
|
|
||||||
RefPtr<SourceSurface> surface =
|
auto result = GetFrameInternal(FRAME_CURRENT, aFlags | FLAG_ASYNC_NOTIFY);
|
||||||
GetFrameInternal(FRAME_CURRENT, FLAG_ASYNC_NOTIFY);
|
if (!result.second()) {
|
||||||
if (!surface) {
|
|
||||||
// The OS threw out some or all of our buffer. We'll need to wait for the
|
// The OS threw out some or all of our buffer. We'll need to wait for the
|
||||||
// redecode (which was automatically triggered by GetFrame) to complete.
|
// redecode (which was automatically triggered by GetFrame) to complete.
|
||||||
return nullptr;
|
return MakePair(result.first(), nsRefPtr<layers::Image>());
|
||||||
}
|
}
|
||||||
|
|
||||||
CairoImage::Data cairoData;
|
CairoImage::Data cairoData;
|
||||||
GetWidth(&cairoData.mSize.width);
|
GetWidth(&cairoData.mSize.width);
|
||||||
GetHeight(&cairoData.mSize.height);
|
GetHeight(&cairoData.mSize.height);
|
||||||
cairoData.mSourceSurface = surface;
|
cairoData.mSourceSurface = result.second();
|
||||||
|
|
||||||
nsRefPtr<layers::Image> image =
|
nsRefPtr<layers::Image> image =
|
||||||
aContainer->CreateImage(ImageFormat::CAIRO_SURFACE);
|
aContainer->CreateImage(ImageFormat::CAIRO_SURFACE);
|
||||||
NS_ASSERTION(image, "Failed to create Image");
|
MOZ_ASSERT(image);
|
||||||
|
|
||||||
static_cast<CairoImage*>(image.get())->SetData(cairoData);
|
static_cast<CairoImage*>(image.get())->SetData(cairoData);
|
||||||
|
|
||||||
return image.forget();
|
return MakePair(result.first(), Move(image));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP_(already_AddRefed<ImageContainer>)
|
||||||
RasterImage::GetImageContainer(LayerManager* aManager, ImageContainer **_retval)
|
RasterImage::GetImageContainer(LayerManager* aManager, uint32_t aFlags)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
MOZ_ASSERT(aManager);
|
MOZ_ASSERT(aManager);
|
||||||
|
MOZ_ASSERT((aFlags & ~(FLAG_SYNC_DECODE |
|
||||||
|
FLAG_SYNC_DECODE_IF_FAST |
|
||||||
|
FLAG_ASYNC_NOTIFY))
|
||||||
|
== FLAG_NONE,
|
||||||
|
"Unsupported flag passed to GetImageContainer");
|
||||||
|
|
||||||
int32_t maxTextureSize = aManager->GetMaxTextureSize();
|
int32_t maxTextureSize = aManager->GetMaxTextureSize();
|
||||||
if (!mHasSize ||
|
if (!mHasSize ||
|
||||||
mSize.width > maxTextureSize ||
|
mSize.width > maxTextureSize ||
|
||||||
mSize.height > maxTextureSize) {
|
mSize.height > maxTextureSize) {
|
||||||
*_retval = nullptr;
|
return nullptr;
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsUnlocked() && mProgressTracker) {
|
if (IsUnlocked() && mProgressTracker) {
|
||||||
@ -818,28 +829,34 @@ RasterImage::GetImageContainer(LayerManager* aManager, ImageContainer **_retval)
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<layers::ImageContainer> container = mImageContainer.get();
|
nsRefPtr<layers::ImageContainer> container = mImageContainer.get();
|
||||||
if (container) {
|
|
||||||
container.forget(_retval);
|
bool mustRedecode =
|
||||||
return NS_OK;
|
(aFlags & (FLAG_SYNC_DECODE | FLAG_SYNC_DECODE_IF_FAST)) &&
|
||||||
|
mLastImageContainerDrawResult != DrawResult::SUCCESS &&
|
||||||
|
mLastImageContainerDrawResult != DrawResult::BAD_IMAGE;
|
||||||
|
|
||||||
|
if (container && !mustRedecode) {
|
||||||
|
return container.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need a new ImageContainer, so create one.
|
// We need a new ImageContainer, so create one.
|
||||||
container = LayerManager::CreateImageContainer();
|
container = LayerManager::CreateImageContainer();
|
||||||
|
|
||||||
nsRefPtr<layers::Image> image = GetCurrentImage(container);
|
auto result = GetCurrentImage(container, aFlags);
|
||||||
if (!image) {
|
if (!result.second()) {
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
// We couldn't get an Image.
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// |image| holds a reference to a SourceSurface which in turn holds a lock on
|
// |result.second()| holds a reference to a SourceSurface which in turn holds
|
||||||
// the current frame's VolatileBuffer, ensuring that it doesn't get freed as
|
// a lock on the current frame's VolatileBuffer, ensuring that it doesn't get
|
||||||
// long as the layer system keeps this ImageContainer alive.
|
// freed as long as the layer system keeps this ImageContainer alive.
|
||||||
container->SetCurrentImageInTransaction(image);
|
container->SetCurrentImageInTransaction(result.second());
|
||||||
|
|
||||||
|
mLastImageContainerDrawResult = result.first();
|
||||||
mImageContainer = container;
|
mImageContainer = container;
|
||||||
container.forget(_retval);
|
|
||||||
|
|
||||||
return NS_OK;
|
return container.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -852,12 +869,14 @@ RasterImage::UpdateImageContainer()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<layers::Image> image = GetCurrentImage(container);
|
auto result = GetCurrentImage(container, FLAG_NONE);
|
||||||
if (!image) {
|
if (!result.second()) {
|
||||||
|
// We couldn't get an Image.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
container->SetCurrentImage(image);
|
mLastImageContainerDrawResult = result.first();
|
||||||
|
container->SetCurrentImage(result.second());
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
@ -1488,12 +1507,6 @@ RasterImage::Decode(const Maybe<nsIntSize>& aSize, uint32_t aFlags)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a decoder.
|
|
||||||
nsRefPtr<Decoder> decoder = CreateDecoder(aSize, aFlags);
|
|
||||||
if (!decoder) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mDownscaleDuringDecode && aSize) {
|
if (mDownscaleDuringDecode && aSize) {
|
||||||
// We're about to decode again, which may mean that some of the previous
|
// We're about to decode again, which may mean that some of the previous
|
||||||
// sizes we've decoded at aren't useful anymore. We can allow them to
|
// sizes we've decoded at aren't useful anymore. We can allow them to
|
||||||
@ -1505,6 +1518,12 @@ RasterImage::Decode(const Maybe<nsIntSize>& aSize, uint32_t aFlags)
|
|||||||
SurfaceCache::UnlockSurfaces(ImageKey(this));
|
SurfaceCache::UnlockSurfaces(ImageKey(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create a decoder.
|
||||||
|
nsRefPtr<Decoder> decoder = CreateDecoder(aSize, aFlags);
|
||||||
|
if (!decoder) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
if (aSize) {
|
if (aSize) {
|
||||||
// This isn't a size decode (which doesn't send any early notifications), so
|
// This isn't a size decode (which doesn't send any early notifications), so
|
||||||
// send out notifications right away.
|
// send out notifications right away.
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/Maybe.h"
|
#include "mozilla/Maybe.h"
|
||||||
#include "mozilla/MemoryReporting.h"
|
#include "mozilla/MemoryReporting.h"
|
||||||
|
#include "mozilla/Pair.h"
|
||||||
#include "mozilla/TimeStamp.h"
|
#include "mozilla/TimeStamp.h"
|
||||||
#include "mozilla/WeakPtr.h"
|
#include "mozilla/WeakPtr.h"
|
||||||
#include "mozilla/UniquePtr.h"
|
#include "mozilla/UniquePtr.h"
|
||||||
@ -297,8 +298,9 @@ private:
|
|||||||
|
|
||||||
TemporaryRef<gfx::SourceSurface> CopyFrame(uint32_t aWhichFrame,
|
TemporaryRef<gfx::SourceSurface> CopyFrame(uint32_t aWhichFrame,
|
||||||
uint32_t aFlags);
|
uint32_t aFlags);
|
||||||
TemporaryRef<gfx::SourceSurface> GetFrameInternal(uint32_t aWhichFrame,
|
|
||||||
uint32_t aFlags);
|
Pair<DrawResult, RefPtr<gfx::SourceSurface>>
|
||||||
|
GetFrameInternal(uint32_t aWhichFrame, uint32_t aFlags);
|
||||||
|
|
||||||
DrawableFrameRef LookupFrameInternal(uint32_t aFrameNum,
|
DrawableFrameRef LookupFrameInternal(uint32_t aFrameNum,
|
||||||
const gfx::IntSize& aSize,
|
const gfx::IntSize& aSize,
|
||||||
@ -314,8 +316,9 @@ private:
|
|||||||
size_t SizeOfDecodedWithComputedFallbackIfHeap(gfxMemoryLocation aLocation,
|
size_t SizeOfDecodedWithComputedFallbackIfHeap(gfxMemoryLocation aLocation,
|
||||||
MallocSizeOf aMallocSizeOf) const;
|
MallocSizeOf aMallocSizeOf) const;
|
||||||
|
|
||||||
already_AddRefed<layers::Image>
|
Pair<DrawResult, nsRefPtr<layers::Image>>
|
||||||
GetCurrentImage(layers::ImageContainer* aContainer);
|
GetCurrentImage(layers::ImageContainer* aContainer, uint32_t aFlags);
|
||||||
|
|
||||||
void UpdateImageContainer();
|
void UpdateImageContainer();
|
||||||
|
|
||||||
// We would like to just check if we have a zero lock count, but we can't do
|
// We would like to just check if we have a zero lock count, but we can't do
|
||||||
@ -381,6 +384,10 @@ private: // data
|
|||||||
// the layer system needs it.
|
// the layer system needs it.
|
||||||
WeakPtr<layers::ImageContainer> mImageContainer;
|
WeakPtr<layers::ImageContainer> mImageContainer;
|
||||||
|
|
||||||
|
// If mImageContainer is non-null, this contains the DrawResult we obtained
|
||||||
|
// the last time we updated it.
|
||||||
|
DrawResult mLastImageContainerDrawResult;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
uint32_t mFramesNotified;
|
uint32_t mFramesNotified;
|
||||||
#endif
|
#endif
|
||||||
|
@ -697,12 +697,10 @@ VectorImage::GetFrame(uint32_t aWhichFrame,
|
|||||||
|
|
||||||
//******************************************************************************
|
//******************************************************************************
|
||||||
/* [noscript] ImageContainer getImageContainer(); */
|
/* [noscript] ImageContainer getImageContainer(); */
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP_(already_AddRefed<ImageContainer>)
|
||||||
VectorImage::GetImageContainer(LayerManager* aManager,
|
VectorImage::GetImageContainer(LayerManager* aManager, uint32_t aFlags)
|
||||||
layers::ImageContainer** _retval)
|
|
||||||
{
|
{
|
||||||
*_retval = nullptr;
|
return nullptr;
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SVGDrawingParameters
|
struct SVGDrawingParameters
|
||||||
|
@ -46,4 +46,4 @@ load multiple-png-hassize.ico
|
|||||||
# Asserts in the debug build
|
# Asserts in the debug build
|
||||||
load 856616.gif
|
load 856616.gif
|
||||||
|
|
||||||
skip-if(AddressSanitizer) load 944353.jpg
|
skip-if(AddressSanitizer) skip-if(B2G) load 944353.jpg
|
||||||
|
@ -707,6 +707,33 @@ MessageChannel::OnMessageReceivedFromLink(const Message& aMsg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MessageChannel::ProcessPendingRequests()
|
||||||
|
{
|
||||||
|
// Loop until there aren't any more priority messages to process.
|
||||||
|
for (;;) {
|
||||||
|
mozilla::Vector<Message> toProcess;
|
||||||
|
|
||||||
|
for (MessageQueue::iterator it = mPending.begin(); it != mPending.end(); ) {
|
||||||
|
Message &msg = *it;
|
||||||
|
if (!ShouldDeferMessage(msg)) {
|
||||||
|
toProcess.append(Move(msg));
|
||||||
|
it = mPending.erase(it);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toProcess.empty())
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Processing these messages could result in more messages, so we
|
||||||
|
// loop around to check for more afterwards.
|
||||||
|
for (auto it = toProcess.begin(); it != toProcess.end(); it++)
|
||||||
|
ProcessPendingRequest(*it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
MessageChannel::Send(Message* aMsg, Message* aReply)
|
MessageChannel::Send(Message* aMsg, Message* aReply)
|
||||||
{
|
{
|
||||||
@ -766,31 +793,12 @@ MessageChannel::Send(Message* aMsg, Message* aReply)
|
|||||||
int32_t transaction = mCurrentTransaction;
|
int32_t transaction = mCurrentTransaction;
|
||||||
msg->set_transaction_id(transaction);
|
msg->set_transaction_id(transaction);
|
||||||
|
|
||||||
|
ProcessPendingRequests();
|
||||||
|
|
||||||
mLink->SendMessage(msg.forget());
|
mLink->SendMessage(msg.forget());
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// Loop until there aren't any more priority messages to process.
|
ProcessPendingRequests();
|
||||||
for (;;) {
|
|
||||||
mozilla::Vector<Message> toProcess;
|
|
||||||
|
|
||||||
for (MessageQueue::iterator it = mPending.begin(); it != mPending.end(); ) {
|
|
||||||
Message &msg = *it;
|
|
||||||
if (!ShouldDeferMessage(msg)) {
|
|
||||||
toProcess.append(Move(msg));
|
|
||||||
it = mPending.erase(it);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
it++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (toProcess.empty())
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Processing these messages could result in more messages, so we
|
|
||||||
// loop around to check for more afterwards.
|
|
||||||
for (auto it = toProcess.begin(); it != toProcess.end(); it++)
|
|
||||||
ProcessPendingRequest(*it);
|
|
||||||
}
|
|
||||||
|
|
||||||
// See if we've received a reply.
|
// See if we've received a reply.
|
||||||
if (mRecvdErrors) {
|
if (mRecvdErrors) {
|
||||||
|
@ -227,6 +227,7 @@ class MessageChannel : HasResultCodes
|
|||||||
bool InterruptEventOccurred();
|
bool InterruptEventOccurred();
|
||||||
bool HasPendingEvents();
|
bool HasPendingEvents();
|
||||||
|
|
||||||
|
void ProcessPendingRequests();
|
||||||
bool ProcessPendingRequest(const Message &aUrgent);
|
bool ProcessPendingRequest(const Message &aUrgent);
|
||||||
|
|
||||||
void MaybeUndeferIncall();
|
void MaybeUndeferIncall();
|
||||||
|
@ -7,9 +7,7 @@ parent:
|
|||||||
prio(high) sync Test1_Start() returns (uint32_t result);
|
prio(high) sync Test1_Start() returns (uint32_t result);
|
||||||
prio(high) sync Test1_InnerEvent() returns (uint32_t result);
|
prio(high) sync Test1_InnerEvent() returns (uint32_t result);
|
||||||
async Test2_Start();
|
async Test2_Start();
|
||||||
prio(high) sync Test2_Msg2();
|
prio(high) sync Test2_OutOfOrder();
|
||||||
prio(high) sync Test2_FirstUrgent();
|
|
||||||
prio(high) sync Test2_SecondUrgent();
|
|
||||||
sync Test3_Start() returns (uint32_t result);
|
sync Test3_Start() returns (uint32_t result);
|
||||||
prio(high) sync Test3_InnerEvent() returns (uint32_t result);
|
prio(high) sync Test3_InnerEvent() returns (uint32_t result);
|
||||||
|
|
||||||
@ -17,8 +15,8 @@ child:
|
|||||||
async Start();
|
async Start();
|
||||||
prio(high) sync Test1_InnerQuery() returns (uint32_t result);
|
prio(high) sync Test1_InnerQuery() returns (uint32_t result);
|
||||||
prio(high) sync Test1_NoReenter() returns (uint32_t result);
|
prio(high) sync Test1_NoReenter() returns (uint32_t result);
|
||||||
prio(high) sync Test2_Msg1();
|
prio(high) sync Test2_FirstUrgent();
|
||||||
prio(high) sync Test2_Msg3();
|
prio(high) sync Test2_SecondUrgent();
|
||||||
prio(high) sync Test3_WakeUp() returns (uint32_t result);
|
prio(high) sync Test3_WakeUp() returns (uint32_t result);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -84,6 +84,8 @@ TestHangsParent::ShouldContinueFromReplyTimeout()
|
|||||||
MessageLoop::current()->PostTask(
|
MessageLoop::current()->PostTask(
|
||||||
FROM_HERE, NewRunnableMethod(this, &TestHangsParent::CleanUp));
|
FROM_HERE, NewRunnableMethod(this, &TestHangsParent::CleanUp));
|
||||||
|
|
||||||
|
GetIPCChannel()->CloseWithTimeout();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,8 @@ namespace _ipdltest {
|
|||||||
// parent
|
// parent
|
||||||
|
|
||||||
TestRPCParent::TestRPCParent()
|
TestRPCParent::TestRPCParent()
|
||||||
|
: reentered_(false),
|
||||||
|
resolved_first_cpow_(false)
|
||||||
{
|
{
|
||||||
MOZ_COUNT_CTOR(TestRPCParent);
|
MOZ_COUNT_CTOR(TestRPCParent);
|
||||||
}
|
}
|
||||||
@ -59,30 +61,25 @@ TestRPCParent::RecvTest1_InnerEvent(uint32_t* aResult)
|
|||||||
bool
|
bool
|
||||||
TestRPCParent::RecvTest2_Start()
|
TestRPCParent::RecvTest2_Start()
|
||||||
{
|
{
|
||||||
if (!SendTest2_Msg1())
|
// Send a CPOW. During this time, we must NOT process the RPC message, as
|
||||||
fail("SendTest2_Msg1");
|
// we could start receiving CPOW replies out-of-order.
|
||||||
|
if (!SendTest2_FirstUrgent())
|
||||||
|
fail("SendTest2_FirstUrgent");
|
||||||
|
|
||||||
|
MOZ_ASSERT(!reentered_);
|
||||||
|
resolved_first_cpow_ = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TestRPCParent::RecvTest2_Msg2()
|
TestRPCParent::RecvTest2_OutOfOrder()
|
||||||
{
|
{
|
||||||
if (!SendTest2_Msg3())
|
// Send a CPOW. If this RPC call was initiated while waiting for the first
|
||||||
fail("SendTest2_Msg3");
|
// CPOW to resolve, replies will be processed out of order, and we'll crash.
|
||||||
|
if (!SendTest2_SecondUrgent())
|
||||||
|
fail("SendTest2_SecondUrgent");
|
||||||
|
|
||||||
return true;
|
reentered_ = true;
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
TestRPCParent::RecvTest2_FirstUrgent()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
TestRPCParent::RecvTest2_SecondUrgent()
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,8 +104,6 @@ TestRPCParent::RecvTest3_InnerEvent(uint32_t* aResult)
|
|||||||
|
|
||||||
|
|
||||||
TestRPCChild::TestRPCChild()
|
TestRPCChild::TestRPCChild()
|
||||||
: reentered_(false),
|
|
||||||
resolved_first_cpow_(false)
|
|
||||||
{
|
{
|
||||||
MOZ_COUNT_CTOR(TestRPCChild);
|
MOZ_COUNT_CTOR(TestRPCChild);
|
||||||
}
|
}
|
||||||
@ -130,8 +125,8 @@ TestRPCChild::RecvStart()
|
|||||||
if (!SendTest2_Start())
|
if (!SendTest2_Start())
|
||||||
fail("SendTest2_Start");
|
fail("SendTest2_Start");
|
||||||
|
|
||||||
if (!SendTest2_Msg2())
|
if (!SendTest2_OutOfOrder())
|
||||||
fail("SendTest2_Msg2");
|
fail("SendTest2_OutOfOrder");
|
||||||
|
|
||||||
result = 0;
|
result = 0;
|
||||||
if (!SendTest3_Start(&result))
|
if (!SendTest3_Start(&result))
|
||||||
@ -163,29 +158,15 @@ TestRPCChild::RecvTest1_NoReenter(uint32_t* aResult)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TestRPCChild::RecvTest2_Msg1()
|
bool
|
||||||
|
TestRPCChild::RecvTest2_FirstUrgent()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(resolved_first_cpow_);
|
|
||||||
|
|
||||||
// Send a CPOW. If this RPC call was initiated while waiting for the first
|
|
||||||
// CPOW to resolve, replies will be processed out of order, and we'll crash.
|
|
||||||
if (!SendTest2_SecondUrgent())
|
|
||||||
fail("SendTest2_SecondUrgent");
|
|
||||||
|
|
||||||
reentered_ = true;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TestRPCChild::RecvTest2_Msg3()
|
TestRPCChild::RecvTest2_SecondUrgent()
|
||||||
{
|
{
|
||||||
// Send a CPOW. During this time, we must NOT process the RPC message, as
|
|
||||||
// we could start receiving CPOW replies out-of-order.
|
|
||||||
if (!SendTest2_FirstUrgent())
|
|
||||||
fail("SendTest2_FirstUrgent");
|
|
||||||
|
|
||||||
MOZ_ASSERT(!reentered_);
|
|
||||||
resolved_first_cpow_ = true;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,9 +25,7 @@ public:
|
|||||||
bool RecvTest1_Start(uint32_t* aResult) MOZ_OVERRIDE;
|
bool RecvTest1_Start(uint32_t* aResult) MOZ_OVERRIDE;
|
||||||
bool RecvTest1_InnerEvent(uint32_t* aResult) MOZ_OVERRIDE;
|
bool RecvTest1_InnerEvent(uint32_t* aResult) MOZ_OVERRIDE;
|
||||||
bool RecvTest2_Start() MOZ_OVERRIDE;
|
bool RecvTest2_Start() MOZ_OVERRIDE;
|
||||||
bool RecvTest2_Msg2() MOZ_OVERRIDE;
|
bool RecvTest2_OutOfOrder() MOZ_OVERRIDE;
|
||||||
bool RecvTest2_FirstUrgent() MOZ_OVERRIDE;
|
|
||||||
bool RecvTest2_SecondUrgent() MOZ_OVERRIDE;
|
|
||||||
bool RecvTest3_Start(uint32_t* aResult) MOZ_OVERRIDE;
|
bool RecvTest3_Start(uint32_t* aResult) MOZ_OVERRIDE;
|
||||||
bool RecvTest3_InnerEvent(uint32_t* aResult) MOZ_OVERRIDE;
|
bool RecvTest3_InnerEvent(uint32_t* aResult) MOZ_OVERRIDE;
|
||||||
|
|
||||||
@ -35,9 +33,17 @@ public:
|
|||||||
{
|
{
|
||||||
if (NormalShutdown != why)
|
if (NormalShutdown != why)
|
||||||
fail("unexpected destruction!");
|
fail("unexpected destruction!");
|
||||||
|
if (!reentered_)
|
||||||
|
fail("never processed raced RPC call!");
|
||||||
|
if (!resolved_first_cpow_)
|
||||||
|
fail("never resolved first CPOW!");
|
||||||
passed("ok");
|
passed("ok");
|
||||||
QuitParent();
|
QuitParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool reentered_;
|
||||||
|
bool resolved_first_cpow_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -51,8 +57,8 @@ public:
|
|||||||
bool RecvStart() MOZ_OVERRIDE;
|
bool RecvStart() MOZ_OVERRIDE;
|
||||||
bool RecvTest1_InnerQuery(uint32_t* aResult) MOZ_OVERRIDE;
|
bool RecvTest1_InnerQuery(uint32_t* aResult) MOZ_OVERRIDE;
|
||||||
bool RecvTest1_NoReenter(uint32_t* aResult) MOZ_OVERRIDE;
|
bool RecvTest1_NoReenter(uint32_t* aResult) MOZ_OVERRIDE;
|
||||||
bool RecvTest2_Msg1() MOZ_OVERRIDE;
|
bool RecvTest2_FirstUrgent() MOZ_OVERRIDE;
|
||||||
bool RecvTest2_Msg3() MOZ_OVERRIDE;
|
bool RecvTest2_SecondUrgent() MOZ_OVERRIDE;
|
||||||
bool RecvTest3_WakeUp(uint32_t* aResult) MOZ_OVERRIDE;
|
bool RecvTest3_WakeUp(uint32_t* aResult) MOZ_OVERRIDE;
|
||||||
|
|
||||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE
|
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE
|
||||||
@ -61,10 +67,6 @@ public:
|
|||||||
fail("unexpected destruction!");
|
fail("unexpected destruction!");
|
||||||
QuitChild();
|
QuitChild();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
bool reentered_;
|
|
||||||
bool resolved_first_cpow_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -138,9 +138,9 @@ TestUrgentHangsChild::RecvTest4()
|
|||||||
{
|
{
|
||||||
PR_Sleep(PR_SecondsToInterval(2));
|
PR_Sleep(PR_SecondsToInterval(2));
|
||||||
|
|
||||||
// This should fail because Test4_1 timed out and hasn't gotten a response
|
// This won't fail because we should handle Test4_1 here before actually
|
||||||
// yet.
|
// sending TestInner to the parent.
|
||||||
if (SendTestInner())
|
if (!SendTestInner())
|
||||||
fail("sending TestInner");
|
fail("sending TestInner");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -4124,6 +4124,97 @@ MLoadElement::foldsTo(TempAllocator &alloc)
|
|||||||
return foldsToStoredValue(alloc, store->value());
|
return foldsToStoredValue(alloc, store->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Gets the MDefinition* representing the source/target object's storage.
|
||||||
|
// Usually this is just an MElements*, but sometimes there are layers
|
||||||
|
// of indirection or inlining, which are handled elsewhere.
|
||||||
|
static inline const MElements *
|
||||||
|
MaybeUnwrapElements(const MDefinition *elementsOrObj)
|
||||||
|
{
|
||||||
|
// Sometimes there is a level of indirection for conversion.
|
||||||
|
if (elementsOrObj->isConvertElementsToDoubles())
|
||||||
|
return MaybeUnwrapElements(elementsOrObj->toConvertElementsToDoubles()->elements());
|
||||||
|
|
||||||
|
// For inline elements, the object may be passed directly, for example as MUnbox.
|
||||||
|
if (elementsOrObj->type() == MIRType_Object)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return elementsOrObj->toElements();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets the MDefinition of the target Object for the given store operation.
|
||||||
|
static inline const MDefinition *
|
||||||
|
GetStoreObject(const MDefinition *store)
|
||||||
|
{
|
||||||
|
switch (store->op()) {
|
||||||
|
case MDefinition::Op_StoreElement: {
|
||||||
|
const MDefinition *elementsOrObj = store->toStoreElement()->elements();
|
||||||
|
const MDefinition *elements = MaybeUnwrapElements(elementsOrObj);
|
||||||
|
if (elements)
|
||||||
|
return elements->toElements()->input();
|
||||||
|
|
||||||
|
MOZ_ASSERT(elementsOrObj->type() == MIRType_Object);
|
||||||
|
return elementsOrObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MDefinition::Op_StoreElementHole:
|
||||||
|
return store->toStoreElementHole()->object();
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implements mightAlias() logic common to all load operations.
|
||||||
|
static bool
|
||||||
|
GenericLoadMightAlias(const MDefinition *elementsOrObj, const MDefinition *store)
|
||||||
|
{
|
||||||
|
const MElements *elements = MaybeUnwrapElements(elementsOrObj);
|
||||||
|
if (elements)
|
||||||
|
return elements->mightAlias(store);
|
||||||
|
|
||||||
|
// If MElements couldn't be extracted, then storage must be inline.
|
||||||
|
// Refer to IsValidElementsType().
|
||||||
|
const MDefinition *object = elementsOrObj;
|
||||||
|
MOZ_ASSERT(object->type() == MIRType_Object);
|
||||||
|
if (!object->resultTypeSet())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
const MDefinition *storeObject = GetStoreObject(store);
|
||||||
|
if (!storeObject)
|
||||||
|
return true;
|
||||||
|
if (!storeObject->resultTypeSet())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return object->resultTypeSet()->objectsIntersect(storeObject->resultTypeSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
MElements::mightAlias(const MDefinition *store) const
|
||||||
|
{
|
||||||
|
if (!input()->resultTypeSet())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
const MDefinition *storeObj = GetStoreObject(store);
|
||||||
|
if (!storeObj)
|
||||||
|
return true;
|
||||||
|
if (!storeObj->resultTypeSet())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return input()->resultTypeSet()->objectsIntersect(storeObj->resultTypeSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
MLoadElement::mightAlias(const MDefinition *store) const
|
||||||
|
{
|
||||||
|
return GenericLoadMightAlias(elements(), store);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
MInitializedLength::mightAlias(const MDefinition *store) const
|
||||||
|
{
|
||||||
|
return GenericLoadMightAlias(elements(), store);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
MGuardReceiverPolymorphic::congruentTo(const MDefinition *ins) const
|
MGuardReceiverPolymorphic::congruentTo(const MDefinition *ins) const
|
||||||
{
|
{
|
||||||
|
@ -7494,6 +7494,7 @@ class MElements
|
|||||||
AliasSet getAliasSet() const MOZ_OVERRIDE {
|
AliasSet getAliasSet() const MOZ_OVERRIDE {
|
||||||
return AliasSet::Load(AliasSet::ObjectFields);
|
return AliasSet::Load(AliasSet::ObjectFields);
|
||||||
}
|
}
|
||||||
|
bool mightAlias(const MDefinition *store) const;
|
||||||
|
|
||||||
ALLOW_CLONE(MElements)
|
ALLOW_CLONE(MElements)
|
||||||
};
|
};
|
||||||
@ -7681,6 +7682,7 @@ class MInitializedLength
|
|||||||
AliasSet getAliasSet() const MOZ_OVERRIDE {
|
AliasSet getAliasSet() const MOZ_OVERRIDE {
|
||||||
return AliasSet::Load(AliasSet::ObjectFields);
|
return AliasSet::Load(AliasSet::ObjectFields);
|
||||||
}
|
}
|
||||||
|
bool mightAlias(const MDefinition *store) const;
|
||||||
|
|
||||||
void computeRange(TempAllocator &alloc) MOZ_OVERRIDE;
|
void computeRange(TempAllocator &alloc) MOZ_OVERRIDE;
|
||||||
|
|
||||||
@ -8184,6 +8186,7 @@ class MLoadElement
|
|||||||
AliasSet getAliasSet() const MOZ_OVERRIDE {
|
AliasSet getAliasSet() const MOZ_OVERRIDE {
|
||||||
return AliasSet::Load(AliasSet::Element);
|
return AliasSet::Load(AliasSet::Element);
|
||||||
}
|
}
|
||||||
|
bool mightAlias(const MDefinition *store) const;
|
||||||
|
|
||||||
ALLOW_CLONE(MLoadElement)
|
ALLOW_CLONE(MLoadElement)
|
||||||
};
|
};
|
||||||
|
@ -419,6 +419,23 @@ TypeSet::isSubset(const TypeSet *other) const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
TypeSet::objectsIntersect(const TypeSet *other) const
|
||||||
|
{
|
||||||
|
if (unknownObject() || other->unknownObject())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < getObjectCount(); i++) {
|
||||||
|
ObjectKey *key = getObject(i);
|
||||||
|
if (!key)
|
||||||
|
continue;
|
||||||
|
if (other->hasType(ObjectType(key)))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
template <class TypeListT>
|
template <class TypeListT>
|
||||||
bool
|
bool
|
||||||
TypeSet::enumerateTypes(TypeListT *list) const
|
TypeSet::enumerateTypes(TypeListT *list) const
|
||||||
|
@ -492,6 +492,8 @@ class TypeSet
|
|||||||
return this->isSubset(other) && other->isSubset(this);
|
return this->isSubset(other) && other->isSubset(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool objectsIntersect(const TypeSet *other) const;
|
||||||
|
|
||||||
/* Forward all types in this set to the specified constraint. */
|
/* Forward all types in this set to the specified constraint. */
|
||||||
bool addTypesToConstraint(JSContext *cx, TypeConstraint *constraint);
|
bool addTypesToConstraint(JSContext *cx, TypeConstraint *constraint);
|
||||||
|
|
||||||
|
@ -3936,6 +3936,7 @@ ContainerState::Finish(uint32_t* aTextContentFlags, LayerManagerData* aData,
|
|||||||
MOZ_ASSERT(layerState == LAYER_ACTIVE_EMPTY);
|
MOZ_ASSERT(layerState == LAYER_ACTIVE_EMPTY);
|
||||||
nsRefPtr<Layer> scrollInfoLayer = item->BuildLayer(mBuilder, mManager, mParameters);
|
nsRefPtr<Layer> scrollInfoLayer = item->BuildLayer(mBuilder, mManager, mParameters);
|
||||||
if (!scrollInfoLayer) {
|
if (!scrollInfoLayer) {
|
||||||
|
item->~nsDisplayScrollInfoLayer();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3972,7 +3973,9 @@ ContainerState::Finish(uint32_t* aTextContentFlags, LayerManagerData* aData,
|
|||||||
}
|
}
|
||||||
|
|
||||||
layer = scrollInfoLayer;
|
layer = scrollInfoLayer;
|
||||||
|
item->~nsDisplayScrollInfoLayer();
|
||||||
}
|
}
|
||||||
|
mNewChildLayers[i].mScrollInfoItems.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5195,13 +5195,11 @@ nsImageRenderer::IsAnimatedImage()
|
|||||||
already_AddRefed<mozilla::layers::ImageContainer>
|
already_AddRefed<mozilla::layers::ImageContainer>
|
||||||
nsImageRenderer::GetContainer(LayerManager* aManager)
|
nsImageRenderer::GetContainer(LayerManager* aManager)
|
||||||
{
|
{
|
||||||
if (mType != eStyleImageType_Image || !mImageContainer)
|
if (mType != eStyleImageType_Image || !mImageContainer) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
nsRefPtr<ImageContainer> container;
|
return mImageContainer->GetImageContainer(aManager, imgIContainer::FLAG_NONE);
|
||||||
nsresult rv = mImageContainer->GetImageContainer(aManager, getter_AddRefs(container));
|
|
||||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
|
||||||
return container.forget();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAX_BLUR_RADIUS 300
|
#define MAX_BLUR_RADIUS 300
|
||||||
|
@ -133,7 +133,8 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mLastDrawResult == mozilla::image::DrawResult::SUCCESS) {
|
if (mLastDrawResult == mozilla::image::DrawResult::SUCCESS ||
|
||||||
|
mLastDrawResult == mozilla::image::DrawResult::BAD_IMAGE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1171,6 +1171,28 @@ public:
|
|||||||
nsDisplayAltFeedback(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
|
nsDisplayAltFeedback(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
|
||||||
: nsDisplayItem(aBuilder, aFrame) {}
|
: nsDisplayItem(aBuilder, aFrame) {}
|
||||||
|
|
||||||
|
virtual nsDisplayItemGeometry*
|
||||||
|
AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
|
||||||
|
{
|
||||||
|
return new nsDisplayItemGenericImageGeometry(this, aBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
|
||||||
|
const nsDisplayItemGeometry* aGeometry,
|
||||||
|
nsRegion* aInvalidRegion) MOZ_OVERRIDE
|
||||||
|
{
|
||||||
|
auto geometry =
|
||||||
|
static_cast<const nsDisplayItemGenericImageGeometry*>(aGeometry);
|
||||||
|
|
||||||
|
if (aBuilder->ShouldSyncDecodeImages() &&
|
||||||
|
geometry->ShouldInvalidateToSyncDecodeImages()) {
|
||||||
|
bool snap;
|
||||||
|
aInvalidRegion->Or(*aInvalidRegion, GetBounds(aBuilder, &snap));
|
||||||
|
}
|
||||||
|
|
||||||
|
nsDisplayItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion);
|
||||||
|
}
|
||||||
|
|
||||||
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
|
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
|
||||||
bool* aSnap) MOZ_OVERRIDE
|
bool* aSnap) MOZ_OVERRIDE
|
||||||
{
|
{
|
||||||
@ -1181,25 +1203,33 @@ public:
|
|||||||
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
||||||
nsRenderingContext* aCtx) MOZ_OVERRIDE
|
nsRenderingContext* aCtx) MOZ_OVERRIDE
|
||||||
{
|
{
|
||||||
|
// Always sync decode, because these icons are UI, and since they're not
|
||||||
|
// discardable we'll pay the price of sync decoding at most once.
|
||||||
|
uint32_t flags = imgIContainer::FLAG_SYNC_DECODE;
|
||||||
|
|
||||||
nsImageFrame* f = static_cast<nsImageFrame*>(mFrame);
|
nsImageFrame* f = static_cast<nsImageFrame*>(mFrame);
|
||||||
EventStates state = f->GetContent()->AsElement()->State();
|
EventStates state = f->GetContent()->AsElement()->State();
|
||||||
f->DisplayAltFeedback(*aCtx,
|
DrawResult result =
|
||||||
mVisibleRect,
|
f->DisplayAltFeedback(*aCtx,
|
||||||
IMAGE_OK(state, true)
|
mVisibleRect,
|
||||||
? nsImageFrame::gIconLoad->mLoadingImage
|
IMAGE_OK(state, true)
|
||||||
: nsImageFrame::gIconLoad->mBrokenImage,
|
? nsImageFrame::gIconLoad->mLoadingImage
|
||||||
ToReferenceFrame());
|
: nsImageFrame::gIconLoad->mBrokenImage,
|
||||||
|
ToReferenceFrame(),
|
||||||
|
flags);
|
||||||
|
|
||||||
|
nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_DISPLAY_DECL_NAME("AltFeedback", TYPE_ALT_FEEDBACK)
|
NS_DISPLAY_DECL_NAME("AltFeedback", TYPE_ALT_FEEDBACK)
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
DrawResult
|
||||||
nsImageFrame::DisplayAltFeedback(nsRenderingContext& aRenderingContext,
|
nsImageFrame::DisplayAltFeedback(nsRenderingContext& aRenderingContext,
|
||||||
const nsRect& aDirtyRect,
|
const nsRect& aDirtyRect,
|
||||||
imgIRequest* aRequest,
|
imgIRequest* aRequest,
|
||||||
nsPoint aPt)
|
nsPoint aPt,
|
||||||
|
uint32_t aFlags)
|
||||||
{
|
{
|
||||||
// We should definitely have a gIconLoad here.
|
// We should definitely have a gIconLoad here.
|
||||||
MOZ_ASSERT(gIconLoad, "How did we succeed in Init then?");
|
MOZ_ASSERT(gIconLoad, "How did we succeed in Init then?");
|
||||||
@ -1219,7 +1249,7 @@ nsImageFrame::DisplayAltFeedback(nsRenderingContext& aRenderingContext,
|
|||||||
// Make sure we have enough room to actually render the border within
|
// Make sure we have enough room to actually render the border within
|
||||||
// our frame bounds
|
// our frame bounds
|
||||||
if ((inner.width < 2 * borderEdgeWidth) || (inner.height < 2 * borderEdgeWidth)) {
|
if ((inner.width < 2 * borderEdgeWidth) || (inner.height < 2 * borderEdgeWidth)) {
|
||||||
return;
|
return DrawResult::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Paint the border
|
// Paint the border
|
||||||
@ -1233,7 +1263,7 @@ nsImageFrame::DisplayAltFeedback(nsRenderingContext& aRenderingContext,
|
|||||||
inner.Deflate(nsPresContext::CSSPixelsToAppUnits(ICON_PADDING+ALT_BORDER_WIDTH),
|
inner.Deflate(nsPresContext::CSSPixelsToAppUnits(ICON_PADDING+ALT_BORDER_WIDTH),
|
||||||
nsPresContext::CSSPixelsToAppUnits(ICON_PADDING+ALT_BORDER_WIDTH));
|
nsPresContext::CSSPixelsToAppUnits(ICON_PADDING+ALT_BORDER_WIDTH));
|
||||||
if (inner.IsEmpty()) {
|
if (inner.IsEmpty()) {
|
||||||
return;
|
return DrawResult::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawTarget* drawTarget = aRenderingContext.GetDrawTarget();
|
DrawTarget* drawTarget = aRenderingContext.GetDrawTarget();
|
||||||
@ -1244,11 +1274,13 @@ nsImageFrame::DisplayAltFeedback(nsRenderingContext& aRenderingContext,
|
|||||||
gfx->Clip(NSRectToSnappedRect(inner, PresContext()->AppUnitsPerDevPixel(),
|
gfx->Clip(NSRectToSnappedRect(inner, PresContext()->AppUnitsPerDevPixel(),
|
||||||
*drawTarget));
|
*drawTarget));
|
||||||
|
|
||||||
// Check if we should display image placeholders
|
DrawResult result = DrawResult::NOT_READY;
|
||||||
if (gIconLoad->mPrefShowPlaceholders) {
|
|
||||||
nscoord size = nsPresContext::CSSPixelsToAppUnits(ICON_SIZE);
|
|
||||||
|
|
||||||
bool iconUsed = false;
|
// Check if we should display image placeholders
|
||||||
|
if (!gIconLoad->mPrefShowPlaceholders) {
|
||||||
|
result = DrawResult::SUCCESS;
|
||||||
|
} else {
|
||||||
|
nscoord size = nsPresContext::CSSPixelsToAppUnits(ICON_SIZE);
|
||||||
|
|
||||||
// If we weren't previously displaying an icon, register ourselves
|
// If we weren't previously displaying an icon, register ourselves
|
||||||
// as an observer for load and animation updates and flag that we're
|
// as an observer for load and animation updates and flag that we're
|
||||||
@ -1262,7 +1294,7 @@ nsImageFrame::DisplayAltFeedback(nsRenderingContext& aRenderingContext,
|
|||||||
bool flushRight =
|
bool flushRight =
|
||||||
(!wm.IsVertical() && !wm.IsBidiLTR()) || wm.IsVerticalRL();
|
(!wm.IsVertical() && !wm.IsBidiLTR()) || wm.IsVerticalRL();
|
||||||
|
|
||||||
// If the icon in question is loaded and decoded, draw it
|
// If the icon in question is loaded, draw it.
|
||||||
uint32_t imageStatus = 0;
|
uint32_t imageStatus = 0;
|
||||||
if (aRequest)
|
if (aRequest)
|
||||||
aRequest->GetImageStatus(&imageStatus);
|
aRequest->GetImageStatus(&imageStatus);
|
||||||
@ -1272,15 +1304,13 @@ nsImageFrame::DisplayAltFeedback(nsRenderingContext& aRenderingContext,
|
|||||||
MOZ_ASSERT(imgCon, "Load complete, but no image container?");
|
MOZ_ASSERT(imgCon, "Load complete, but no image container?");
|
||||||
nsRect dest(flushRight ? inner.XMost() - size : inner.x,
|
nsRect dest(flushRight ? inner.XMost() - size : inner.x,
|
||||||
inner.y, size, size);
|
inner.y, size, size);
|
||||||
nsLayoutUtils::DrawSingleImage(*gfx, PresContext(), imgCon,
|
result = nsLayoutUtils::DrawSingleImage(*gfx, PresContext(), imgCon,
|
||||||
nsLayoutUtils::GetGraphicsFilterForFrame(this), dest, aDirtyRect,
|
nsLayoutUtils::GetGraphicsFilterForFrame(this), dest, aDirtyRect,
|
||||||
nullptr, imgIContainer::FLAG_SYNC_DECODE);
|
nullptr, aFlags);
|
||||||
iconUsed = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we could not draw the icon, flag that we're waiting for it and
|
// If we could not draw the icon, just draw some graffiti in the mean time.
|
||||||
// just draw some graffiti in the mean time
|
if (result == DrawResult::NOT_READY) {
|
||||||
if (!iconUsed) {
|
|
||||||
ColorPattern color(ToDeviceColor(Color(1.f, 0.f, 0.f, 1.f)));
|
ColorPattern color(ToDeviceColor(Color(1.f, 0.f, 0.f, 1.f)));
|
||||||
|
|
||||||
nscoord iconXPos = flushRight ? inner.XMost() - size : inner.x;
|
nscoord iconXPos = flushRight ? inner.XMost() - size : inner.x;
|
||||||
@ -1331,6 +1361,8 @@ nsImageFrame::DisplayAltFeedback(nsRenderingContext& aRenderingContext,
|
|||||||
}
|
}
|
||||||
|
|
||||||
aRenderingContext.ThebesContext()->Restore();
|
aRenderingContext.ThebesContext()->Restore();
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@ -1395,9 +1427,11 @@ already_AddRefed<ImageContainer>
|
|||||||
nsDisplayImage::GetContainer(LayerManager* aManager,
|
nsDisplayImage::GetContainer(LayerManager* aManager,
|
||||||
nsDisplayListBuilder* aBuilder)
|
nsDisplayListBuilder* aBuilder)
|
||||||
{
|
{
|
||||||
nsRefPtr<ImageContainer> container;
|
uint32_t flags = aBuilder->ShouldSyncDecodeImages()
|
||||||
mImage->GetImageContainer(aManager, getter_AddRefs(container));
|
? imgIContainer::FLAG_SYNC_DECODE
|
||||||
return container.forget();
|
: imgIContainer::FLAG_NONE;
|
||||||
|
|
||||||
|
return mImage->GetImageContainer(aManager, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxRect
|
gfxRect
|
||||||
@ -1457,8 +1491,12 @@ nsDisplayImage::GetLayerState(nsDisplayListBuilder* aBuilder,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<ImageContainer> container;
|
uint32_t flags = aBuilder->ShouldSyncDecodeImages()
|
||||||
mImage->GetImageContainer(aManager, getter_AddRefs(container));
|
? imgIContainer::FLAG_SYNC_DECODE
|
||||||
|
: imgIContainer::FLAG_NONE;
|
||||||
|
|
||||||
|
nsRefPtr<ImageContainer> container =
|
||||||
|
mImage->GetImageContainer(aManager, flags);
|
||||||
if (!container) {
|
if (!container) {
|
||||||
return LAYER_NONE;
|
return LAYER_NONE;
|
||||||
}
|
}
|
||||||
@ -1502,9 +1540,15 @@ nsDisplayImage::BuildLayer(nsDisplayListBuilder* aBuilder,
|
|||||||
LayerManager* aManager,
|
LayerManager* aManager,
|
||||||
const ContainerLayerParameters& aParameters)
|
const ContainerLayerParameters& aParameters)
|
||||||
{
|
{
|
||||||
nsRefPtr<ImageContainer> container;
|
uint32_t flags = aBuilder->ShouldSyncDecodeImages()
|
||||||
nsresult rv = mImage->GetImageContainer(aManager, getter_AddRefs(container));
|
? imgIContainer::FLAG_SYNC_DECODE
|
||||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
: imgIContainer::FLAG_NONE;
|
||||||
|
|
||||||
|
nsRefPtr<ImageContainer> container =
|
||||||
|
mImage->GetImageContainer(aManager, flags);
|
||||||
|
if (!container) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
nsRefPtr<ImageLayer> layer = static_cast<ImageLayer*>
|
nsRefPtr<ImageLayer> layer = static_cast<ImageLayer*>
|
||||||
(aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, this));
|
(aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, this));
|
||||||
|
@ -143,10 +143,11 @@ public:
|
|||||||
static bool ShouldCreateImageFrameFor(mozilla::dom::Element* aElement,
|
static bool ShouldCreateImageFrameFor(mozilla::dom::Element* aElement,
|
||||||
nsStyleContext* aStyleContext);
|
nsStyleContext* aStyleContext);
|
||||||
|
|
||||||
void DisplayAltFeedback(nsRenderingContext& aRenderingContext,
|
DrawResult DisplayAltFeedback(nsRenderingContext& aRenderingContext,
|
||||||
const nsRect& aDirtyRect,
|
const nsRect& aDirtyRect,
|
||||||
imgIRequest* aRequest,
|
imgIRequest* aRequest,
|
||||||
nsPoint aPt);
|
nsPoint aPt,
|
||||||
|
uint32_t aFlags);
|
||||||
|
|
||||||
nsRect GetInnerArea() const;
|
nsRect GetInnerArea() const;
|
||||||
|
|
||||||
|
@ -433,13 +433,18 @@ nsDisplayXULImage::ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<ImageContainer>
|
already_AddRefed<ImageContainer>
|
||||||
nsDisplayXULImage::GetContainer(LayerManager* aManager, nsDisplayListBuilder* aBuilder)
|
nsDisplayXULImage::GetContainer(LayerManager* aManager,
|
||||||
|
nsDisplayListBuilder* aBuilder)
|
||||||
{
|
{
|
||||||
return static_cast<nsImageBoxFrame*>(mFrame)->GetContainer(aManager);
|
uint32_t flags = aBuilder->ShouldSyncDecodeImages()
|
||||||
|
? imgIContainer::FLAG_SYNC_DECODE
|
||||||
|
: imgIContainer::FLAG_NONE;
|
||||||
|
|
||||||
|
return static_cast<nsImageBoxFrame*>(mFrame)->GetContainer(aManager, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<ImageContainer>
|
already_AddRefed<ImageContainer>
|
||||||
nsImageBoxFrame::GetContainer(LayerManager* aManager)
|
nsImageBoxFrame::GetContainer(LayerManager* aManager, uint32_t aFlags)
|
||||||
{
|
{
|
||||||
bool hasSubRect = !mUseSrcAttr && (mSubRect.width > 0 || mSubRect.height > 0);
|
bool hasSubRect = !mUseSrcAttr && (mSubRect.width > 0 || mSubRect.height > 0);
|
||||||
if (hasSubRect || !mImageRequest) {
|
if (hasSubRect || !mImageRequest) {
|
||||||
@ -452,9 +457,7 @@ nsImageBoxFrame::GetContainer(LayerManager* aManager)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<ImageContainer> container;
|
return imgCon->GetImageContainer(aManager, aFlags);
|
||||||
imgCon->GetImageContainer(aManager, getter_AddRefs(container));
|
|
||||||
return container.forget();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ class nsImageBoxFrame MOZ_FINAL : public nsLeafBoxFrame
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef mozilla::image::DrawResult DrawResult;
|
typedef mozilla::image::DrawResult DrawResult;
|
||||||
|
typedef mozilla::layers::ImageContainer ImageContainer;
|
||||||
typedef mozilla::layers::LayerManager LayerManager;
|
typedef mozilla::layers::LayerManager LayerManager;
|
||||||
|
|
||||||
friend class nsDisplayXULImage;
|
friend class nsDisplayXULImage;
|
||||||
@ -95,7 +96,9 @@ public:
|
|||||||
const nsRect& aDirtyRect,
|
const nsRect& aDirtyRect,
|
||||||
nsPoint aPt, uint32_t aFlags);
|
nsPoint aPt, uint32_t aFlags);
|
||||||
|
|
||||||
already_AddRefed<mozilla::layers::ImageContainer> GetContainer(LayerManager* aManager);
|
already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager,
|
||||||
|
uint32_t aFlags);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit nsImageBoxFrame(nsStyleContext* aContext);
|
explicit nsImageBoxFrame(nsStyleContext* aContext);
|
||||||
|
|
||||||
|
@ -1789,8 +1789,9 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
|
|||||||
}
|
}
|
||||||
duration = ntohl(duration32);
|
duration = ntohl(duration32);
|
||||||
}
|
}
|
||||||
if (duration) {
|
if (duration && mHeaderTimescale) {
|
||||||
mFileMetaData->setInt64(kKeyMovieDuration, duration * 1000LL);
|
mFileMetaData->setInt64(
|
||||||
|
kKeyMovieDuration, (duration * 1000000) / mHeaderTimescale);
|
||||||
}
|
}
|
||||||
|
|
||||||
*offset += chunk_size;
|
*offset += chunk_size;
|
||||||
|
@ -26,9 +26,11 @@
|
|||||||
#include "nsNetCID.h"
|
#include "nsNetCID.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
#include "nsICancelable.h"
|
#include "nsICancelable.h"
|
||||||
|
#include "nsIDocument.h"
|
||||||
|
#include "nsILoadInfo.h"
|
||||||
|
#include "nsIContentPolicy.h"
|
||||||
#include "nsIProxyInfo.h"
|
#include "nsIProxyInfo.h"
|
||||||
#include "nsIProtocolProxyService.h"
|
#include "nsIProtocolProxyService.h"
|
||||||
#include "nsIIOService.h"
|
|
||||||
|
|
||||||
#ifdef MOZILLA_INTERNAL_API
|
#ifdef MOZILLA_INTERNAL_API
|
||||||
#include "MediaStreamList.h"
|
#include "MediaStreamList.h"
|
||||||
@ -227,15 +229,14 @@ PeerConnectionMedia::PeerConnectionMedia(PeerConnectionImpl *parent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIIOService> ios = do_GetIOService(&rv);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
CSFLogError(logTag, "%s: Failed to get IOService: %d",
|
|
||||||
__FUNCTION__, (int)rv);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIChannel> channel;
|
nsCOMPtr<nsIChannel> channel;
|
||||||
rv = ios->NewChannelFromURI(fakeHttpsLocation, getter_AddRefs(channel));
|
nsCOMPtr<nsIDocument> doc = mParent->GetWindow()->GetExtantDoc();
|
||||||
|
rv = NS_NewChannel(getter_AddRefs(channel),
|
||||||
|
fakeHttpsLocation,
|
||||||
|
doc,
|
||||||
|
nsILoadInfo::SEC_NORMAL,
|
||||||
|
nsIContentPolicy::TYPE_OTHER);
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
CSFLogError(logTag, "%s: Failed to get channel from URI: %d",
|
CSFLogError(logTag, "%s: Failed to get channel from URI: %d",
|
||||||
__FUNCTION__, (int)rv);
|
__FUNCTION__, (int)rv);
|
||||||
|
12
mfbt/Pair.h
12
mfbt/Pair.h
@ -166,6 +166,18 @@ public:
|
|||||||
|
|
||||||
Pair(const Pair& aOther) = default;
|
Pair(const Pair& aOther) = default;
|
||||||
|
|
||||||
|
Pair& operator=(Pair&& aOther)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(this != &aOther, "Self-moves are prohibited");
|
||||||
|
|
||||||
|
first() = Move(aOther.first());
|
||||||
|
second() = Move(aOther.second());
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pair& operator=(const Pair& aOther) = default;
|
||||||
|
|
||||||
/** The A instance. */
|
/** The A instance. */
|
||||||
using Base::first;
|
using Base::first;
|
||||||
/** The B instance. */
|
/** The B instance. */
|
||||||
|
@ -75,5 +75,9 @@ main()
|
|||||||
static_assert(IsSame<decltype(MakePair(constA, constB)), Pair<A, B>>::value,
|
static_assert(IsSame<decltype(MakePair(constA, constB)), Pair<A, B>>::value,
|
||||||
"MakePair should strip CV-qualifiers");
|
"MakePair should strip CV-qualifiers");
|
||||||
|
|
||||||
|
// Check that copy assignment and move assignment work.
|
||||||
|
a = constA;
|
||||||
|
a = A(0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -566,6 +566,7 @@ pref("media.fragmented-mp4.android-media-codec.enabled", true);
|
|||||||
pref("media.fragmented-mp4.android-media-codec.preferred", true);
|
pref("media.fragmented-mp4.android-media-codec.preferred", true);
|
||||||
|
|
||||||
// optimize images memory usage
|
// optimize images memory usage
|
||||||
|
pref("image.downscale-during-decode.enabled", true);
|
||||||
pref("image.mem.decodeondraw", true);
|
pref("image.mem.decodeondraw", true);
|
||||||
|
|
||||||
#ifdef NIGHTLY_BUILD
|
#ifdef NIGHTLY_BUILD
|
||||||
|
@ -427,10 +427,10 @@ pref("media.getusermedia.screensharing.enabled", true);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef RELEASE_BUILD
|
#ifdef RELEASE_BUILD
|
||||||
pref("media.getusermedia.screensharing.allowed_domains", "webex.com,*.webex.com,collaborate.com,*.collaborate.com,projectsquared.com,*.projectsquared.com,*.room.co,room.co,beta.talky.io,talky.io,*.clearslide.com,appear.in,*.appear.in,tokbox.com,*.tokbox.com,*.sso.francetelecom.fr,*.si.francetelecom.fr,*.sso.infra.ftgroup,*.multimedia-conference.orange-business.com,*.espacecollaboration.orange-business.com,free.gotomeeting.com,g2m.me,*.g2m.me,example.com");
|
pref("media.getusermedia.screensharing.allowed_domains", "webex.com,*.webex.com,ciscospark.com,*.ciscospark.com,projectsquared.com,*.projectsquared.com,*.room.co,room.co,beta.talky.io,talky.io,*.clearslide.com,appear.in,*.appear.in,tokbox.com,*.tokbox.com,*.sso.francetelecom.fr,*.si.francetelecom.fr,*.sso.infra.ftgroup,*.multimedia-conference.orange-business.com,*.espacecollaboration.orange-business.com,free.gotomeeting.com,g2m.me,*.g2m.me,example.com");
|
||||||
#else
|
#else
|
||||||
// temporary value, not intended for release - bug 1049087
|
// temporary value, not intended for release - bug 1049087
|
||||||
pref("media.getusermedia.screensharing.allowed_domains", "mozilla.github.io,webex.com,*.webex.com,collaborate.com,*.collaborate.com,projectsquared.com,*.projectsquared.com,*.room.co,room.co,beta.talky.io,talky.io,*.clearslide.com,appear.in,*.appear.in,tokbox.com,*.tokbox.com,*.sso.francetelecom.fr,*.si.francetelecom.fr,*.sso.infra.ftgroup,*.multimedia-conference.orange-business.com,*.espacecollaboration.orange-business.com,free.gotomeeting.com,g2m.me,*.g2m.me,example.com");
|
pref("media.getusermedia.screensharing.allowed_domains", "mozilla.github.io,webex.com,*.webex.com,ciscospark.com,*.ciscospark.com,projectsquared.com,*.projectsquared.com,*.room.co,room.co,beta.talky.io,talky.io,*.clearslide.com,appear.in,*.appear.in,tokbox.com,*.tokbox.com,*.sso.francetelecom.fr,*.si.francetelecom.fr,*.sso.infra.ftgroup,*.multimedia-conference.orange-business.com,*.espacecollaboration.orange-business.com,free.gotomeeting.com,g2m.me,*.g2m.me,example.com");
|
||||||
#endif
|
#endif
|
||||||
// OS/X 10.6 and XP have screen/window sharing off by default due to various issues - Caveat emptor
|
// OS/X 10.6 and XP have screen/window sharing off by default due to various issues - Caveat emptor
|
||||||
pref("media.getusermedia.screensharing.allow_on_old_platforms", false);
|
pref("media.getusermedia.screensharing.allow_on_old_platforms", false);
|
||||||
@ -3001,7 +3001,7 @@ pref("intl.keyboard.per_window_layout", false);
|
|||||||
|
|
||||||
#ifdef NS_ENABLE_TSF
|
#ifdef NS_ENABLE_TSF
|
||||||
// Enable/Disable TSF support on Vista or later.
|
// Enable/Disable TSF support on Vista or later.
|
||||||
#ifdef NIGHTLY_BUILD
|
#ifndef RELEASE_BUILD
|
||||||
pref("intl.tsf.enable", true);
|
pref("intl.tsf.enable", true);
|
||||||
#else
|
#else
|
||||||
pref("intl.tsf.enable", false);
|
pref("intl.tsf.enable", false);
|
||||||
@ -3819,7 +3819,7 @@ pref("image.cache.size", 5242880);
|
|||||||
pref("image.cache.timeweight", 500);
|
pref("image.cache.timeweight", 500);
|
||||||
|
|
||||||
// Whether we attempt to downscale images during decoding.
|
// Whether we attempt to downscale images during decoding.
|
||||||
pref("image.downscale-during-decode.enabled", false);
|
pref("image.downscale-during-decode.enabled", true);
|
||||||
|
|
||||||
// The default Accept header sent for images loaded over HTTP(S)
|
// The default Accept header sent for images loaded over HTTP(S)
|
||||||
pref("image.http.accept", "image/png,image/*;q=0.8,*/*;q=0.5");
|
pref("image.http.accept", "image/png,image/*;q=0.8,*/*;q=0.5");
|
||||||
@ -4628,14 +4628,10 @@ pref("media.gmp.insecure.allow", false);
|
|||||||
|
|
||||||
// Use vsync aligned rendering. b2g prefs are in b2g.js
|
// Use vsync aligned rendering. b2g prefs are in b2g.js
|
||||||
// Only supported on windows, os x, and b2g
|
// Only supported on windows, os x, and b2g
|
||||||
#if defined(XP_MACOSX)
|
#if defined(XP_MACOSX) || defined(XP_WIN)
|
||||||
pref("gfx.vsync.hw-vsync.enabled", true);
|
pref("gfx.vsync.hw-vsync.enabled", true);
|
||||||
pref("gfx.vsync.compositor", true);
|
pref("gfx.vsync.compositor", true);
|
||||||
pref("gfx.vsync.refreshdriver", false);
|
pref("gfx.vsync.refreshdriver", false);
|
||||||
#elif defined(XP_WIN)
|
|
||||||
pref("gfx.vsync.hw-vsync.enabled", false);
|
|
||||||
pref("gfx.vsync.compositor", false);
|
|
||||||
pref("gfx.vsync.refreshdriver", false);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Secure Element API
|
// Secure Element API
|
||||||
|
@ -3149,6 +3149,10 @@ nsHttpChannel::OnCacheEntryCheck(nsICacheEntry* entry, nsIApplicationCache* appC
|
|||||||
mRedirectedCachekeys->AppendElement(cacheKey);
|
mRedirectedCachekeys->AppendElement(cacheKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (doValidation && mInterceptCache == INTERCEPTED) {
|
||||||
|
doValidation = false;
|
||||||
|
}
|
||||||
|
|
||||||
mCachedContentIsValid = !doValidation;
|
mCachedContentIsValid = !doValidation;
|
||||||
|
|
||||||
if (doValidation) {
|
if (doValidation) {
|
||||||
|
@ -1,20 +1,12 @@
|
|||||||
[mediasource-addsourcebuffer.html]
|
[mediasource-addsourcebuffer.html]
|
||||||
type: testharness
|
type: testharness
|
||||||
[Test addSourceBuffer() with Vorbis and VP8]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Test addSourceBuffer() with Vorbis and VP8 in separate SourceBuffers]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Test addSourceBuffer() with AAC and H.264]
|
[Test addSourceBuffer() with AAC and H.264]
|
||||||
expected: FAIL
|
expected:
|
||||||
|
if os == "linux": FAIL
|
||||||
|
if (os == "win") and (version == "5.1.2600"): FAIL
|
||||||
|
|
||||||
[Test addSourceBuffer() with AAC and H.264 in separate SourceBuffers]
|
[Test addSourceBuffer() with AAC and H.264 in separate SourceBuffers]
|
||||||
expected: FAIL
|
expected:
|
||||||
|
if os == "linux": FAIL
|
||||||
[Test addSourceBuffer() video only]
|
if (os == "win") and (version == "5.1.2600"): FAIL
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Test addSourceBuffer() audio only]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
|
@ -1,21 +1,5 @@
|
|||||||
[mediasource-append-buffer.html]
|
[mediasource-append-buffer.html]
|
||||||
type: testharness
|
type: testharness
|
||||||
disabled:
|
disabled:
|
||||||
if (os == "win") and (version != "5.1.2600"): https://bugzilla.mozilla.org/show_bug.cgi?id=1128332
|
if (os == "win") and (version != "5.1.2600"): https://bugzilla.mozilla.org/show_bug.cgi?id=1143650
|
||||||
[Test MediaSource.removeSourceBuffer() call during a pending appendBuffer().]
|
if os == "mac": https://bugzilla.mozilla.org/show_bug.cgi?id=1143650
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Test appendBuffer with partial init segments.]
|
|
||||||
expected:
|
|
||||||
if (os == "win") and (version != "5.1.2600"): FAIL
|
|
||||||
if os == "mac": FAIL
|
|
||||||
|
|
||||||
[Test appendBuffer with partial media segments.]
|
|
||||||
expected:
|
|
||||||
if (os == "win") and (version != "5.1.2600"): FAIL
|
|
||||||
if os == "mac": FAIL
|
|
||||||
|
|
||||||
[Test abort in the middle of an initialization segment.]
|
|
||||||
disabled:
|
|
||||||
if (os == "win") and (version != "5.1.2600"): https://bugzilla.mozilla.org/show_bug.cgi?id=1128332
|
|
||||||
|
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
[mediasource-buffered.html]
|
[mediasource-buffered.html]
|
||||||
type: testharness
|
type: testharness
|
||||||
[Demuxed content with different lengths]
|
[Demuxed content with different lengths]
|
||||||
expected: FAIL
|
expected:
|
||||||
|
if os == "linux": FAIL
|
||||||
|
if (os == "win") and (version == "5.1.2600"): FAIL
|
||||||
|
|
||||||
[Muxed tracks with different lengths]
|
[Muxed tracks with different lengths]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
[mediasource-config-change-mp4-av-audio-bitrate.html]
|
[mediasource-config-change-mp4-av-audio-bitrate.html]
|
||||||
type: testharness
|
type: testharness
|
||||||
[Tests mp4 audio bitrate changes in multiplexed content.]
|
[Tests mp4 audio bitrate changes in multiplexed content.]
|
||||||
expected: FAIL
|
expected:
|
||||||
|
if os == "linux": FAIL
|
||||||
|
if (os == "win") and (version == "5.1.2600"): FAIL
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user